[ODT] Codeforces 896C. Willem, Chtholly and Seniorious

来源:互联网 发布:编程语言c 怎么用 编辑:程序博客网 时间:2024/06/07 07:05

据ODT在CF上说,是一种叫ODT的树

用平衡树维护区间,暴力修改维护这些区间。

因为数据随机,所以跑得快…

发现自己不会用SET………

#include <cstdio>#include <iostream>#include <algorithm>#include <set>#include <map>#include <vector>#include <assert.h>#define mp make_pair#define fi first#define se second#define pb push_backusing namespace std;typedef long long ll;typedef pair<int,int> seg;map<seg,ll> S;int n,m,seed,vmax;inline int ran(){  int ret=seed;  seed=(7LL*seed+13)%1000000007;  return ret;}inline int Pow(ll x,ll y,ll P){  int ret=1; x%=P;  for(;y;y>>=1,x=x*x%P) if(y&1) ret=x*ret%P;  return ret;}int main(){  freopen("1.in","r",stdin);  freopen("1.out","w",stdout);  scanf("%d%d%d%d",&n,&m,&seed,&vmax);  for(int i=1;i<=n;i++){    int cur=ran()%vmax+1;    S[seg(i,i)]=cur;  }  for(int i=1;i<=m;i++){    int opt=ran()%4+1,l=ran()%n+1,r=ran()%n+1,x,y;    if(l>r) swap(l,r);    if(opt==3) x=ran()%(r-l+1)+1;    else x=ran()%vmax+1;    if(opt==4) y=ran()%vmax+1;    if(opt==1){      map<seg,ll>::iterator IT=S.upper_bound(seg(l-1,1<<30));      if(IT->fi.fi!=l){    IT--;    seg a1=seg(IT->fi.fi,l-1),a2=seg(l,min(r,IT->fi.se)); ll c=IT->se;    if(IT->fi.se>r){      seg a3=seg(r+1,IT->fi.se);      S.erase(IT); S[a1]=c; S[a2]=c+x; S[a3]=c;    }    else S.erase(IT),S[a1]=c,S[a2]=c+x;    IT=S.upper_bound(seg(l,1<<30));      }      while(IT!=S.end() && IT->fi.fi<=r){    if(IT->fi.se<=r) IT->se+=x;    else{      int L=IT->fi.fi,R=IT->fi.se; ll v=IT->se;      S.erase(IT);      S[seg(L,r)]=v+x; S[seg(r+1,R)]=v;      break;    }    IT++;      }    }    else if(opt==2){      map<seg,ll>::iterator IT=S.upper_bound(seg(l-1,1<<30));      if(IT->fi.fi!=l){    IT--;    seg a1=seg(IT->fi.fi,l-1),a2=seg(l,min(r,IT->fi.se)); ll c=IT->se;    if(IT->fi.se>r){      seg a3=seg(r+1,IT->fi.se);      S.erase(IT); S[a3]=c;    }    else S.erase(IT);    S[a1]=c;    IT=S.upper_bound(seg(l,1<<30));      }      while(IT!=S.end() && IT->fi.fi<=r){    if(IT->fi.se<=r) S.erase(IT);    else{      int L=r+1,R=IT->fi.se; ll v=IT->se;      S.erase(IT); S[seg(L,R)]=v; break;    }    IT=S.upper_bound(seg(l-1,1<<30));      }      S[seg(l,r)]=x;    }    else if(opt==3){      vector<pair<ll,int> > v;      map<seg,ll>::iterator IT=S.upper_bound(seg(l-1,1<<30));      if(IT->fi.fi!=l){    IT--;    v.pb(mp(IT->se,min(r,IT->fi.se)-l+1));    IT++;      }      while(IT!=S.end() && IT->fi.fi<=r){    v.pb(mp(IT->se,min(IT->fi.se,r)-IT->fi.fi+1)); IT++;      }      sort(v.begin(),v.end());      for(int j=0;j<v.size();j++){    if(v[j].se>=x){      printf("%lld\n",v[j].fi);      break;    }    x-=v[j].se;      }    }    else{      map<seg,ll>::iterator IT=S.upper_bound(seg(l-1,1<<30));      int ans=0;      if(IT->fi.fi!=l){    IT--;    ans=(ans+1LL*Pow(IT->se,x,y)*(min(r,IT->fi.se)-l+1))%y;    IT++;      }      while(IT!=S.end() && IT->fi.fi<=r){    if(IT->fi.se<=r) ans=(ans+1LL*Pow(IT->se,x,y)*(IT->fi.se-IT->fi.fi+1))%y;    else{      ans=(ans+1LL*Pow(IT->se,x,y)*(r-IT->fi.fi+1))%y; break;    }    IT++;      }      printf("%d\n",ans);    }    //printf("Case %d:\n",i);    //printf("%d %d %d %d %d\n",opt,l,r,x,y);    //for(auto c : S) printf("%d %d %lld\n",c.fi.fi,c.fi.se,c.se);  }  return 0;}
阅读全文
0 0
原创粉丝点击