因为x<=60所以可以建立60颗线段树,这些线段树是区间赋值,然后再建立一颗记录答案的线段树,每当第一颗线段树上发生推平操作的时候,第二颗线段树也进行更新,当推平不了的时候暴力下方。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using i128=__int128;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using db = double;
using ldb = long double;
#define F first
#define S second
#define debug(x) cerr<<#x<<":"<<x<<"\n";
#define debugv(v) cerr<<#v<<":\n";for(int i=1;i<v.size();i++) cerr<<v[i]<<" ";cout<<"\n";
const int N=3e5+10;
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
pii operator+(const pii x,const pii y){
if(x.F==y.F) return {x.F,x.S+y.S};
if(x.F>y.F) return x;
return y;
}
struct segtree2{
struct node{
int l,r,tag;
pii num;
}t[N<<2];
segtree2(){
build(1,1,3e5);
}
void pushup(int p){
t[p].num=t[ls(p)].num+t[rs(p)].num;
}
void build(int p,int l,int r){
t[p].l=l,t[p].r=r;
if(l==r){
t[p].tag=0;
t[p].num={0,1};
return;
}
int mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
pushup(p);
}
void addtag(int p,int d){
t[p].tag+=d;
t[p].num.F+=d;
}
void pushdown(int p){
if(t[p].tag){
addtag(ls(p),t[p].tag);
addtag(rs(p),t[p].tag);
t[p].tag=0;
}
}
pii query(int l,int r,int p){
if(l<=t[p].l&&t[p].r<=r){
return t[p].num;
}
pushdown(p);
int mid=(t[p].l+t[p].r)>>1;
pii ans={0,0};
if(l<=mid) ans=ans+query(l,r,ls(p));
if(mid<r) ans=ans+query(l,r,rs(p));
return ans;
}
void update(int l,int r,int p,int d){
if(l<=t[p].l&&t[p].r<=r){
addtag(p,d);
return;
}
pushdown(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid) update(l,r,ls(p),d);
if(mid<r) update(l,r,rs(p),d);
pushup(p);
}
}seg;
struct segtree1{
struct node{
int l,r,num,tag;
}t[N<<2];
segtree1(){
build(1,1,3e5);
}
void pushup(int p){
t[p].num=t[ls(p)].num+t[rs(p)].num;
}
void build(int p,int l,int r){
t[p].l=l,t[p].r=r;
if(l==r){
t[p].num=t[p].tag=0;
return;
}
int mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
pushup(p);
}
void addtag(int p,int d){
t[p].tag+=d;
t[p].num+=d*(t[p].r-t[p].l+1);
}
void pushdown(int p){
if(t[p].tag){
addtag(ls(p),t[p].tag);
addtag(rs(p),t[p].tag);
t[p].tag=0;
}
}
void update(int l,int r,int p,int d){
if(l<=t[p].l&&t[p].r<=r){
if(d==1){
if(t[p].num==t[p].r-t[p].l+1){return;}
else if(t[p].num==0){addtag(p,d);seg.update(t[p].l,t[p].r,1,1);return;}
}else{
if(t[p].num==t[p].r-t[p].l+1){addtag(p,d);seg.update(t[p].l,t[p].r,1,-1);return;}
else if(t[p].num==0){return;}
}
}
pushdown(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid) update(l,r,ls(p),d);
if(mid<r) update(l,r,rs(p),d);
pushup(p);
}
}t1[61];
void solve(){
int n,q;cin>>n>>q;
while(q--){
int op;cin>>op;
if(op==1){
int l,r,x;cin>>l>>r>>x;
t1[x].update(l,r,1,1);
}else if(op==2){
int l,r,x;cin>>l>>r>>x;
t1[x].update(l,r,1,-1);
}else{
int l,r;cin>>l>>r;
pii ans=seg.query(l,r,1);
cout<<ans.F<<" "<<ans.S<<"\n";
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int t=1;
// cin>>t;
while(t--) solve();
return 0;
}

京公网安备 11010502036488号