珂朵莉树模板(珂朵莉树)

orz yzhang

学会了一个叫做mutable的关键字

关键操作:Split,将指定位置的区间拆开

洛谷CF896C Willem, Chtholly and Seniorious

#include<bits/stdc++.h>
#define LL long long
#define I inline
#define R register int
using namespace std;
struct Node{
    mutable int l,r;mutable LL v;
    I Node(R a,R b=0,LL c=0):l(a),r(b),v(c){}
    I bool operator<(const Node&a)const{
        return l<a.l;
    }
};
typedef set<Node>::iterator IT;
set<Node>s;
IT d[100009];
I bool operator<(const IT&a,const IT&b){
    return a->v<b->v;
}
I IT Split(R p){
    IT it=s.lower_bound(Node(p));
    if(it!=s.end()&&it->l==p)return it;
    R r=(--it)->r;it->r=p;
    return s.insert(Node(p,r,it->v)).first;
}
int n,m,seed,vmax;
I int Rand(){
    R ret=seed;
    seed=((LL)seed*7+13)%1000000007;
    return ret;
}
I LL Pow(LL b,R k,LL YL,LL a=1){
    for(b%=YL;k;k>>=1,b=b*b%YL)
        if(k&1)a=a*b%YL;
    return a;
}
int main(){
    ios::sync_with_stdio(0);
    cin>>n>>m>>seed>>vmax;
    for(R i=1;i<=n;++i)
        s.insert(Node(i,i+1,Rand()%vmax+1));
    for(R i=1;i<=m;++i){
        R op=Rand()%4+1,l=Rand()%n+1,r=Rand()%n+1,p=0;
        if(l>r)swap(l,r);++r;
        R x=Rand()%(op==3?r-l:vmax)+1;
        IT it=Split(l),en=r>n?s.end():Split(r);
        switch(op){
        case 1:
            for(;it!=en;++it)it->v+=x;
            break;
        case 2:
            s.erase(it,en);
            s.insert(Node(l,r,x));
            break;
        case 3:
            for(;it!=en;++it)d[++p]=it;
            sort(d+1,d+p+1);
            for(p=1;x>0;++p)x-=d[p]->r-d[p]->l;
            cout<<d[p-1]->v<<'\n';
            break;
        case 4:
            LL YL=Rand()%vmax+1,ans=0;
            for(;it!=en;++it)ans=(ans+Pow(it->v,x,YL)*(it->r-it->l))%YL;
            cout<<ans<<endl;
        }
    }
    return 0;
}
posted @ 2019-01-19 16:48  Flash_Hu  阅读(1241)  评论(7编辑  收藏  举报