luogu P3710 方方方的数据结构
作者:互联网
题面传送门
有撤销还可以离线。
就显然可以找到每个操作的左右端点。
然后写了线段树分治
这个东西之所以不能线段树分治的原因是因为他是要求顺序的。
所以直接写个高维数据结构即可。
因为不想写kdt所以写了个四分树反正数据随机
code:
#include<cstdio>
#include<vector>
#define N 150000
#define I inline
#define ll long long
#define mod 998244353
using namespace std;
int n,m,k,x,y,z,op[N+5],l[N+5],r[N+5],w[N+5],id[N+5],root;
struct pai{
ll a,b;
I int have(){return b||(a^1);}
pai operator +(const pai &x)const{return (pai){a*x.a%mod,(b*x.a+x.b)%mod};}
}st=(pai){1,0};
struct tree{
pai f[N+5<<5];int cnt,son[N+5<<5][4];
I void push(int x,pai w){x&&(f[x]=f[x]+w,0);}
I void pushdown(int x){if(!f[x].have()) return;for(int i=0;i<=3;i++) push(son[x][i],f[x]);f[x]=st;}
I void make(int x,int y,int l=1,int ls=n,int r=1,int rs=m,int &now=root){
!now&&(now=++cnt);f[now]=st;if(l==ls&&r==rs) return;int ml=l+ls>>1,mr=r+rs>>1;
x<=ml&&(y<=mr?make(x,y,l,ml,r,mr,son[now][0]):make(x,y,l,ml,mr+1,rs,son[now][1]),0);
x>ml&&(y<=mr?make(x,y,ml+1,ls,r,mr,son[now][2]):make(x,y,ml+1,ls,mr+1,rs,son[now][3]),0);
}
I void get(int x,int y,int xs,int ys,pai w,int l=1,int ls=n,int r=1,int rs=m,int now=root){
if(!now) return;if(x<=l&&ls<=y&&xs<=r&&rs<=ys) return push(now,w);pushdown(now);int ml=l+ls>>1,mr=r+rs>>1;
if(x<=ml&&xs<=mr) get(x,y,xs,ys,w,l,ml,r,mr,son[now][0]);
if(x<=ml&&ys>mr) get(x,y,xs,ys,w,l,ml,mr+1,rs,son[now][1]);
if(y>ml&&xs<=mr) get(x,y,xs,ys,w,ml+1,ls,r,mr,son[now][2]);
if(y>ml&&ys>mr) get(x,y,xs,ys,w,ml+1,ls,mr+1,rs,son[now][3]);
}
I ll find(int x,int y,int l=1,int ls=n,int r=1,int rs=m,int now=root){
if(l==ls&&r==rs) return f[now].b;pushdown(now);int ml=l+ls>>1,mr=r+rs>>1;
if(x<=ml)return y<=mr?find(x,y,l,ml,r,mr,son[now][0]):find(x,y,l,ml,mr+1,rs,son[now][1]);
else return y<=mr?find(x,y,ml+1,ls,r,mr,son[now][2]):find(x,y,ml+1,ls,mr+1,rs,son[now][3]);
}
}s;
int main(){
freopen("1.in","r",stdin); freopen("1.out","w",stdout);
register int i;scanf("%d%d",&n,&m);
for(i=1;i<=m;i++) scanf("%d",&op[i]),op[i]<=2?(scanf("%d%d%d",&l[i],&r[i],&w[i]),w[i]%=mod):(scanf("%d",&w[i])),id[i]=m;
for(i=1;i<=m;i++) op[i]==3&&(s.make(w[i],i),0),op[i]==4&&(id[w[i]]=i);
for(i=1;i<=m;i++){
op[i]<=2&&(s.get(l[i],r[i],i,id[i],op[i]^1?(pai){w[i],0}:(pai){1,w[i]}),0);
op[i]==3&&(printf("%lld\n",s.find(w[i],i)));//printf("%lld\n",s.find(2,4));
}
}
标签:now,rs,int,luogu,P3710,ls,mr,pai,数据结构 来源: https://www.cnblogs.com/275307894a/p/14727567.html