【CodeForces-896C】— Willem, Chtholly and Seniorious(ODT老驱动树)

传送门

ODTODT真是个好暴力 的东西

但是只有在随机数据下才有用(当然如果随机数据都把你卡了又有什么办法,就好像TreapTreap生成了一条链一样)

而且只能在有区间覆盖操作的里面

因为考虑到覆盖之后整个区间都是同样的数了

那我们可以把这一个区间压成一个点

最后我们就得到了很多个点

修改询问的时候都直接整体修改就可以了

然后就像暴力一样遍历整个区间就完了

注意随时取膜,否则到处爆longlonglonglong

#include<bits/stdc++.h>
using namespace std;
#define gc getchar
#define ll long long
#define int long long
#define IT set<node>::iterator
#define pi pair<ll,int>
#define mp(x,y) make_pair(x,y)
inline int read(){
	int res=0,f=1;
	char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
	while((isdigit(ch)))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
	return res;
}
#undef gc
ll seed,mxv;
inline ll rnd(){
	int res=seed;
	seed=(seed*7+13)%1000000007;
	return res;
}
const int N=100005;
int n,m;
ll a[N];
struct node{
	int l,r;
	mutable ll val;
	node(int L,int R=-1,ll v=0):l(L),r(R),val(v){}
	bool operator < (const  node &a)const {return l<a.l;}
};
set<node>st;
inline ll ksm(ll a,ll b,ll mod){
	int res=1;a%=mod;
	for(;b;b>>=1,a=a*a%mod){
		if(b&1)res=res*a%mod;
	}
	return res;
}
inline IT split(int pos){
	IT it=st.lower_bound(node(pos));
	if(it!=st.end()&&it->l==pos)return it;
	it--;
	int l=it->l,r=it->r;
	ll val=it->val;
	st.erase(it);
	st.insert(node(l,pos-1,val));
	return st.insert(node(pos,r,val)).first;
}
inline void assign(int l,int r,ll val){
	IT itr=split(r+1),itl=split(l);
	st.erase(itl,itr);
	st.insert(node(l,r,val));	
}
inline void add(int l,int r,int val){
	IT itr=split(r+1),itl=split(l);
	for(;itl!=itr;itl++)itl->val+=val;
}
inline ll kth(int l,int r,int k){
	vector<pi>vec;
	IT itr=split(r+1),itl=split(l);
	for(;itl!=itr;itl++)
	vec.push_back(mp(itl->val,itl->r-itl->l+1));
	sort(vec.begin(),vec.end());
	for(vector<pi>::iterator it=vec.begin();it!=vec.end();it++){
		k-=it->second;
		if(k<=0)return it->first;
	}
	return -1;
}
ll sum(int l,int r,ll x,ll y){
    ll res=0;
    IT itr=split(r+1),itl=split(l);
    for(;itl!=itr;++itl)
    res+=(ksm(itl->val,x,y)*((itl->r-itl->l+1)%y))%y,res%=y;
    return res;
}
signed main(){
    n=read();m=read();
    seed=read();mxv=read();
    for(int i=1;i<=n;++i){
        a[i]=(rnd()%mxv)+1;
        st.insert(node(i,i,a[i]));
    }
    for(int i=1;i<=m;++i){
        int op=(rnd()%4)+1;
        int l=(rnd()%n)+1,r=(rnd()%n)+1;
        ll x,y;
    	if(l>r) swap(l,r);
    	if(op==3) x=(rnd()%(r-l+1))+1;
    	else x=(rnd()%mxv)+1;
    	if(op==4) y=(rnd()%mxv)+1;
    	if(op==1) add(l,r,x);
    	else if(op==2) assign(l,r,x);
    	else if(op==3) printf("%lld\n",kth(l,r,x));
    	else if(op==4) printf("%lld\n",sum(l,r,x,y));
    }
    return 0;
}
posted @ 2019-01-21 16:45  Stargazer_cykoi  阅读(158)  评论(0编辑  收藏  举报