CF896C Willem, Chtholly and Seniorious

珂朵莉树\雾

刚开始把每个数都当做一个区间;分裂操作很重要(有些细节);推平时直接 erase 掉区间的 iterator ,单独插一个回去;区间加时把所有 iterator 分裂出来,直接加;区间第 \(k\) 大把区间 \([l,r]\) 里的所有 iterator 取出来按权值 vl 排序;区间 \(k\) 次方我们还是把区间所有的 iterator 取出来然后计算即可。

#include<iostream>
#include<cstdio>
#include<set>
#include<vector>
#include<algorithm>
#define I set<node>::iterator
#define R register int
#define ll long long	
using namespace std;
namespace Luitaryi {
inline int g() { R x=0,f=1;
  register char s; while(!isdigit(s=getchar())) f=s=='-'?-1:f;
  do x=x*10+(s^48); while(isdigit(s=getchar())); return x*f;
} const int M=1000000007,N=100010;
struct node {
  int l,r; mutable ll vl;
  node(int l,int r=-1,ll vl=0):l(l),r(r),vl(vl) {}
  inline bool operator < (const node& that) const {return l<that.l;}
};
inline int qpow(int a,int b,int M) { R ret=1;
  for(;b;b>>=1,a=1ll*a*a%M) if(b&1) ret=1ll*ret*a%M; return ret;
}
set<node> s;
inline I split(int pos) {
  I it=s.lower_bound(node(pos));
  if(it!=s.end()&&it->l==pos) return it;
  --it;
  R LL=it->l,RR=it->r;
  register ll vl=it->vl;
  s.erase(it); 
  s.insert(node(LL,pos-1,vl));
  return s.insert(node(pos,RR,vl)).first;
}
inline void add(int l,int r,int vl) {
  I RR=split(r+1),LL=split(l);
  while(LL!=RR) LL->vl+=vl,++LL;
}
inline void flat(int l,int r,int vl) {
  I RR=split(r+1),LL=split(l);
  s.erase(LL,RR),s.insert(node(l,r,vl));
}
vector<pair<ll,int> > mem;
inline ll getvl(int l,int r,int k) {
  mem.clear();
  I RR=split(r+1),LL=split(l);
  while(LL!=RR) mem.push_back(make_pair(LL->vl,LL->r-LL->l+1)),++LL;
  sort(mem.begin(),mem.end());
  for(const auto& v:mem) {
    k-=v.second;
    if(k<=0) return v.first;
  } return -1;
}
inline int query(int l,int r,int b,int M) {
  I RR=split(r+1),LL=split(l);
  R ret=0;
  while(LL!=RR) ret=(ret+1ll*(LL->r-LL->l+1)*qpow(LL->vl%M,b,M))%M,++LL;
  return ret;
}
int n,m;
int sed,V;
inline int rnd() {
  R ret=sed;
  sed=(1ll*sed*7+13)%M;
  return ret;
}
inline void main() {
  n=g(),m=g(),sed=g(),V=g();
  for(R i=1;i<=n;++i) 
    s.insert(node(i,i,rnd()%V+1));
  s.insert(node(n+1,n+1,0));
  for(R i=1,op,l,r,x,y;i<=m;++i) {
    op=rnd()%4+1,l=rnd()%n+1,r=rnd()%n+1;
    if(l>r) swap(l,r);
    if(op==3) x=rnd()%(r-l+1)+1;
    else x=rnd()%V+1;
    if(op==4) y=rnd()%V+1;
    if(op==1) add(l,r,x);
    if(op==2) flat(l,r,x);
    if(op==3) printf("%I64d\n",getvl(l,r,x));
    if(op==4) printf("%d\n",query(l,r,x,y));
  }
}
} signed main() {Luitaryi::main(); return 0;}


2019.01.16

posted @ 2020-01-16 18:58  LuitaryiJack  阅读(255)  评论(0编辑  收藏  举报