1. 程式人生 > >Codeforces 896C Willem, Chtholly and Seniorious 珂朵莉樹

Codeforces 896C Willem, Chtholly and Seniorious 珂朵莉樹

文章目錄

下午寫了一個小時發現快速冪寫萎了.f__k!!! 終於把一個坑給填了.珂學真是太棒了.

題意

,,k,.區間加,區間推平,區間第k大,區間乘方和取模.

解法

區間推平操作+資料隨機.用珂朵莉樹維護,均攤的時間複雜度是lognlogn. 謝謝大家.

#include<bits/stdc++.h> //Ithea Myse Valgulious
namespace chtholly{
typedef long long ll;
#define re0 register int
#define
rel register ll
#define rec register char #define gc getchar //#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<23,stdin),p1==p2)?-1:*p1++) #define pc putchar #define p32 pc(' ') #define pl puts("") /*By Citrus*/ char buf[1<<23],*p1=buf,*p2=buf; inline int read(){ int x=0,f=1;char
c=gc(); for (;!isdigit(c);c=gc()) f^=c=='-'; for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0'); return f?x:-x; } template <typename mitsuha> inline bool read(mitsuha &x){ x=0;int f=1;char c=gc(); for (;!isdigit(c)&&~c;c=gc()) f^=c=='-'; if (!~c) return 0; for
(;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0'); return x=f?x:-x,1; } template <typename mitsuha> inline int write(mitsuha x){ if (!x) return 0&pc(48); if (x<0) pc('-'),x=-x; int bit[20],i,p=0; for (;x;x/=10) bit[++p]=x%10; for (i=p;i;--i) pc(bit[i]+48); return 0; } inline char fuhao(){ char c=gc(); for (;isspace(c);c=gc()); return c; } }using namespace chtholly; using namespace std; int n,q,vmax,seed; int rnd() { int ret=seed; seed=(seed*7ll+13)%1000000007; return ret; } ll kasumi(ll a,ll b,ll mod){ ll s=1; for (a%=mod;b;b>>=1,a=a*a%mod) if (b&1) s=s*a%mod; return s; }/*快速冪寫萎了......a一定要先模mod!*/ struct chtholly_tree{ struct node{ int l,r; mutable ll v; node(int nl,int nr=-1,ll val=0):l(nl),r(nr),v(val) {} bool operator <(const node &b) const{ return l<b.l; } }; typedef set<node>::iterator it; set<node> s; it split(int pos) { it p=s.lower_bound(pos); if (p!=s.end()&&p->l==pos) return p; --p; int l=p->l,r=p->r; ll v=p->v; s.erase(p); s.insert(node(l,pos-1,v)); return s.insert(node(pos,r,v)).first; } void assign(int l,int r,int v) { it itr=split(r+1),itl=split(l); s.erase(itl,itr); s.insert(node(l,r,v)); } void add(int l,int r,int v){ it p,itr=split(r+1),itl=split(l); for (p=itl;p!=itr;++p) p->v+=v; } ll kth(int l,int r,int k,int i=0) { it p,itr=split(r+1),itl=split(l); vector<node> llx; for (p=itl;p!=itr;++p) llx.push_back(*p); sort(llx.begin(),llx.end(),[](node a,node b){return a.v<b.v;}); /*所以我過載cmp為什麼不給過啊!一定要我用lambda表示式!*/ for (i=0;i<llx.size()&&k>0;++i) k-=llx[i].r-llx[i].l+1; return llx[i-1].v; } ll query(int l,int r,int x,int y){ it p,itr=split(r+1),itl=split(l); ll zxy=0; for (p=itl;p!=itr;++p) zxy=(zxy+1ll*(p->r-p->l+1)*kasumi(p->v,x,y))%y; return zxy; } void init(int n) { for (int i=1;i<=n;++i) s.insert(node(i,i,rnd()%vmax+1)); } }my_; int main() { read(n),read(q); read(seed),read(vmax); my_.init(n); int cnt=0; for (;q--;) { int op=rnd()%4+1,l,r,x,y; l=rnd()%n+1,r=rnd()%n+1; if (l>r) swap(l,r); switch(op) { case 3: x=rnd()%(r-l+1)+1; write(my_.kth(l,r,x)),pl; break; case 4: x=rnd()%vmax+1; y=rnd()%vmax+1; write(my_.query(l,r,x,y)),pl; break; case 1: x=rnd()%vmax+1; my_.add(l,r,x); break; case 2: x=rnd()%vmax+1; my_.assign(l,r,x); break; } } }