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

据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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值