珂朵莉树模板

模板题:CF896C

#include<bits/stdc++.h>
#define SIT set<ODT>::iterator
#define VIT vector<pair<long long,long long>>::iterator
using namespace std;
const int N=400010;
long long pw(long long a,long long b,long long mod){
    long long res=1;
    a%=mod;
    while(b){
        if(b&1)res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
struct ODT{
    int l,r;
    mutable long long v;
    ODT(int L,int R=-1,long long V=0){
        l=L,r=R,v=V;
    }
};
bool operator <(ODT A,ODT B){
    return A.l<B.l;
}
set<ODT>s;
int n,m;
long long a[N];
long long seed,vmax;
SIT split(int pos){
    SIT it=s.lower_bound(ODT(pos)),num=it;
    num--;
    ODT IT=*it,now=*num;
    if(it!=s.end()&&IT.l==pos)return it;
    int L=now.l,R=now.r;
    long long V=now.v;
    s.erase(num);
    s.insert(ODT(L,pos-1,V));
    return s.insert(ODT(pos,R,V)).first;
}
void add(int L,int R,long long V=1){
    SIT itl=split(L),itr=split(R+1);
    while(itl!=itr){
        (*itl).v+=V;
        itl++;
    }
}
void assign(int L,int R,long long V){
    SIT itl=split(L),itr=split(R+1);
    s.erase(itl,itr);
    s.insert(ODT(L,R,V)); 
}
long long _kth(int L,int R,long long K=0){
    vector<pair<long long,long long>>Q;
    SIT itl=split(L),itr=split(R+1);
    Q.clear();
    while(itl!=itr){
        ODT now=*itl;
        Q.push_back(make_pair(now.v,(long long)now.r-now.l+1));
        itl++;
    }
    sort(Q.begin(),Q.end());
    for(VIT i=Q.begin();i<Q.end();i++){
        K-=(*i).second;
        if(K<=0)return (*i).first;
    }
    return -1LL;
}
long long powsum(int L,int R,long long K,long long mod){
    SIT itl=split(L),itr=split(R+1);
    long long res=0;
    while(itl!=itr){
        ODT now=*itl;
        res=(res+(long long)(now.r-now.l+1)*pw(now.v,K,mod))%mod;
        itl++;
    }
    return res;
}
long long rnd(){
    long long ret=seed;
    seed=(seed*7+13)%1000000007;
    return ret;    
}
int main(){
    scanf("%d%d%lld%lld",&n,&m,&seed,&vmax);
    for(int i=1;i<=n;i++){
        a[i]=(rnd()%vmax)+1;
        s.insert(ODT(i,i,a[i]));
    }
    s.insert(ODT(n+1,n+1,0));
    for(int i=1;i<=m;i++){    
        int opt=(rnd()%4)+1;
        int l=(rnd()%n)+1;
        int r=(rnd()%n)+1;
        if(l>r)swap(l,r);
        int x=0,y=0;
        if (opt==3)x=(rnd()%(r-l+1))+1;
        else x=(rnd()%vmax)+1;
        if (opt==4)y=(rnd()%vmax)+1;
        if(opt==1){
            add(l,r,(long long)x);
        }else if(opt==2){
            assign(l,r,(long long)x);
        }else if(opt==3){
            printf("%lld\n",_kth(l,r,(long long)x));
        }else{
            printf("%lld\n",powsum(l,r,(long long)x,(long long)y));
        }
    }
}
ODT

注释以后再补上....

posted @ 2020-02-03 16:42  passione  阅读(170)  评论(0编辑  收藏  举报