ODT&(Avito Code Challenge 2018 G题)
记录大模拟一般新数据结构(ODT)
#include <bits/stdc++.h> #define ll long long #define pii pair<int,int> #define s second #define f first #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,r,l) for(int i=r;i>=l;i--) const int MAXN=2e5+10; const ll mod=998244353; using namespace std; ll read(){ ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return f*x; } set<pii>s[MAXN]; set<pii>::iterator ite,ip,id; int n,q; typedef struct node{ ll tag1,tag2,sum;int l,r; }node; node d[MAXN<<2]; void push(int x){ if(d[x].tag1>1){ d[x<<1].tag1*=d[x].tag1;d[x<<1].tag1%=mod; d[x<<1|1].tag1*=d[x].tag1;d[x<<1|1].tag1%=mod; d[x<<1].tag2*=d[x].tag1;d[x<<1].tag2%=mod; d[x<<1|1].tag2*=d[x].tag1;d[x<<1|1].tag2%=mod; d[x<<1].sum*=d[x].tag1;d[x<<1].sum%=mod; d[x<<1|1].sum*=d[x].tag1;d[x<<1|1].sum%=mod; d[x].tag1=1; } if(d[x].tag2){ d[x<<1].tag2+=d[x].tag2;d[x<<1].tag2%=mod; d[x<<1|1].tag2+=d[x].tag2;d[x<<1|1].tag2%=mod; d[x<<1].sum+=1ll*(d[x<<1].r-d[x<<1].l+1)*d[x].tag2; d[x<<1].sum%=mod; d[x<<1|1].sum+=1ll*(d[x<<1|1].r-d[x<<1|1].l+1)*d[x].tag2; d[x<<1|1].sum%=mod; d[x].tag2=0; } } void up(int x){d[x].sum=d[x<<1].sum+d[x<<1|1].sum;} void built(int rt,int l,int r){ if(l==r){d[rt].l=d[rt].r=l;d[rt].tag1=1;d[rt].tag2=d[rt].sum=0;return ;} int mid=(l+r)>>1; built(rt<<1,l,mid); built(rt<<1|1,mid+1,r); d[rt].l=d[rt<<1].l;d[rt].r=d[rt<<1|1].r; d[rt].tag1=1;d[rt].tag2=d[rt].sum=0; up(rt); } void update1(int rt,int l,int r,int ql,int qr){ if(ql<=l&&r<=qr){ d[rt].tag1*=2ll;d[rt].tag2*=2ll;d[rt].sum*=2ll; d[rt].tag1%=mod;d[rt].tag2%=mod;d[rt].sum%=mod; return ; } push(rt); int mid=(l+r)>>1; if(ql<=mid)update1(rt<<1,l,mid,ql,qr); if(qr>mid)update1(rt<<1|1,mid+1,r,ql,qr); up(rt); } //新建 void update2(int rt,int l,int r,int ql,int qr){ if(ql<=l&&r<=qr){ d[rt].tag2+=1ll;d[rt].sum+=1ll*(r-l+1); d[rt].tag2%=mod;d[rt].sum%=mod; return ; } push(rt); int mid=(l+r)>>1; if(ql<=mid)update2(rt<<1,l,mid,ql,qr); if(qr>mid)update2(rt<<1|1,mid+1,r,ql,qr); up(rt); } ll sum=0; void querty(int rt,int l,int r,int ql,int qr){ if(ql<=l&&r<=qr){ sum+=d[rt].sum;sum%=mod; return ; } int mid=(l+r)>>1; push(rt); if(ql<=mid)querty(rt<<1,l,mid,ql,qr); if(qr>mid)querty(rt<<1|1,mid+1,r,ql,qr); up(rt); } int main(){ n=read();q=read(); built(1,1,n); int op,l,r,vul; for(int i=1;i<=q;i++){ op=read();l=read();r=read(); if(op==1){ vul=read();int flag1=0,flag2=0; ite=s[vul].lower_bound(make_pair(l,0)); if(s[vul].begin()==s[vul].end()){ s[vul].insert(make_pair(l,r)); update2(1,1,n,l,r); continue; } // cout<<ite->first<<" "<<ite->second<<endl; // cout<<s[vul].size()<<"----"<<endl; if(ite==s[vul].end()){ //cout<<"sb"<<endl; ite--; if(ite->second<l){ s[vul].insert(make_pair(l,r)); update2(1,1,n,l,r); continue; } else{ int l1=ite->first;int r1=ite->second; s[vul].erase(make_pair(l1,r1)); s[vul].insert(make_pair(l1,l-1)); s[vul].insert(make_pair(l,r1)); } } else if(ite==s[vul].begin()&&ite->first!=l){ // cout<<"AC"<<endl; if(r<ite->first){ s[vul].insert(make_pair(l,r)); update2(1,1,n,l,r);continue; } else{ flag1=1; //cout<<"AC"<<endl; //cout<<ite->first<<" "<<ite->second<<endl; s[vul].insert(make_pair(l,ite->first-1)); update2(1,1,n,l,ite->first-1); } } else if(ite->first!=l){ //cout<<ite->first<<" "<<ite->second<<endl; int lx=ite->first;ite--; if(ite->second<l){ flag1=1; if(lx<=r){ s[vul].insert(make_pair(l,lx-1)); update2(1,1,n,l,lx-1);} else{ s[vul].insert(make_pair(l,r)); update2(1,1,n,l,r); continue; } } else{ int l1=ite->first;int r1=ite->second; //cout<<l1<<" "<<r1<<endl; s[vul].erase(make_pair(l1,r1)); s[vul].insert(make_pair(l1,l-1)); s[vul].insert(make_pair(l,r1)); } } // cout<<"SB"<<endl; ip=s[vul].lower_bound(make_pair(r,0)); //if(ip==s[vul].end())cout<<"Yes"<<endl; //cout<<ip->first<<" "<<ip->second<<endl; if(ip==s[vul].end()||ip->first>r){ ip--; if(ip->second<r){ flag2=1; //cout<<"AC"<<endl; //cout<<ip->second<<endl; update2(1,1,n,ip->second+1,r); //if(r==ip->second+1)s[vul].insert(make_pair(r,r)); if(r!=ip->second+1) s[vul].insert(make_pair(ip->second+1,r-1)),flag2=2; s[vul].insert(make_pair(r,r)); } else{ int l1=ip->first;int r1=ip->second; //cout<<l1<<" "<<r1<<endl; s[vul].erase(make_pair(l1,r1)); if(l1!=r) s[vul].insert(make_pair(l1,r-1)); s[vul].insert(make_pair(r,r)); if(r!=r1) s[vul].insert(make_pair(r+1,r1)); } } else{ int l1=ip->first;int r1=ip->second; //cout<<l1<<" "<<r1<<endl; s[vul].erase(make_pair(l1,r1)); s[vul].insert(make_pair(r,r)); if(r!=r1) s[vul].insert(make_pair(r+1,r1)); } ite=s[vul].lower_bound(make_pair(l,0)); ip=s[vul].lower_bound(make_pair(r,0)); if(flag2==2)ip--; //cout<<ite->first<<" "<<ite->second<<endl; //cout<<flag1<<endl; id=s[vul].end(); if(!flag1) update1(1,1,n,ite->first,ite->second); //else id=ite; id=ite;ite++; //cout<<flag1<<endl; if(ite!=s[vul].end()&&id!=ip){ //cout<<"AC"<<endl; for(;ite!=ip;ite++){ //cout<<"sb"<<endl; if(ite->first-id->second>1){ update2(1,1,n,id->second+1,ite->first-1); } update1(1,1,n,ite->first,ite->second); id=ite; } if(ip->first-id->second>1){ //cout<<"sb"<<endl; update2(1,1,n,id->second+1,ip->first-1); } if(!flag2) update1(1,1,n,ip->first,ip->second);} //cout<<flag2<<endl; ite=s[vul].lower_bound(make_pair(l,0)); ip=s[vul].lower_bound(make_pair(r,0)); ip++; s[vul].erase(ite,ip); s[vul].insert(make_pair(l,r)); } else{ sum=0; //cout<<l<<" "<<r<<endl; querty(1,1,n,l,r); printf("%lld\n",sum); } } return 0; }