欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-02-24 11:16:07
...

据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_back

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