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;
}

浙公网安备 33010602011771号