66pts求条
查看原帖
66pts求条
701478
_FastFT2013楼主2024/7/22 17:25
#include<iostream>
#include<algorithm>
#include<set>
#include<vector>
#define con const
#define iit set<odt>::iterator
using namespace std;
const int N=5e5+5;
const int M=1e5+5;
int n,m,seed,vmax;
int l[M],r[M],x[M],y[M],a[N],op[M];
const int mod=1e9+7;
int rnd(){
	int ret=seed;
	seed=(1ll*seed*7+13)%mod;
	return ret;
}
int qpow(long long a,long long b,long long p){
	long long sum=1;
	a%=p;
	while(b){
		if(b&1){
			sum=(sum*a)%p;
		}
		a=a*a%p;
		b>>=1;
	}
	return sum;
}
struct odt{
	int l,r;
	mutable long long v;
	odt(con int ll,con int rr,con long long val){
		l=ll;
		r=rr;
		v=val;
	}
	bool operator<(odt b)const{
		return l<b.l;
	}
};
bool cmp(odt a,odt b){
	return a.v<b.v;
}
set<odt>od;
iit split(int pos){
	iit it=od.lower_bound(odt{pos,0,0});
	if(it!=od.end()&&it->l==pos){
		return it;
	}
	--it;
	if(it->r<pos)return od.end();
	int ll=it->l,rr=it->r,v=it->v;
	od.erase(it);
	od.insert(odt(ll,pos-1,v));
	return od.insert(odt(pos,rr,v)).first;
}
void assighn(int l,int r,int v){
	iit rr=split(r+1),ll=split(l);
	od.erase(ll,rr);
	od.insert(odt(l,r,v));
}
void add(int l,int r,int v){
	iit rr=split(r+1),ll=split(l);
	for(iit it=ll;it!=rr;it++){
		it->v+=v;
	}
}
vector<odt>v;
int ask(int l,int r,int x){
	iit rr=split(r+1),ll=split(l);
	v.clear();
	for(iit it=ll;it!=rr;it++){
		v.push_back(*it);
	}
	sort(v.begin(),v.end(),cmp);
	int sum=0;
	for(auto t:v){
		if(sum+(t.r-t.l+1)>=x){
			return t.v;
		}
		sum+=(t.r-t.l+1);
	}
	return sum;
}
int query(int l,int r,int x,int y){
	iit rr=split(r+1),ll=split(l);
	long long sum=0;
	for(iit it=ll;it!=rr;it++){
		sum+=(it->r-it->l+1)%y*qpow(it->v,x,y)%y;
		sum%=y;
	}
	return sum;
}
int main(){
	cin>>n>>m>>seed>>vmax;
	for(int i=1;i<=n;i++){
		a[i]=(rnd()%vmax)+1;
	}
	for(int i=1;i<=m;i++){
		op[i]=(rnd()%4)+1;
		l[i]=(rnd()%n)+1;
		r[i]=(rnd()%n)+1;
		if(l[i]>r[i])swap(l[i],r[i]);
		if(op[i]==3){
			x[i]=(rnd()%(r[i]-l[i]+1))+1;
		}else{
			x[i]=(rnd()%vmax)+1;
		}
		if(op[i]==4){
			y[i]=(rnd()%vmax)+1;
		}
	}
	for(int i=1;i<=n;){
		int j=i;
		while(a[j+1]==a[i]&&j<=n)j++;
		od.insert(odt(i,j,a[i]));
		i=j+1;
	}
	for(int i=1;i<=m;i++){
		if(op[i]==1){
			add(l[i],r[i],x[i]);
		}else if(op[i]==2){
			assighn(l[i],r[i],x[i]);
		}else if(op[i]==3){
			cout<<ask(l[i],r[i],x[i])<<"\n";
		}else{
			cout<<query(l[i],r[i],x[i],y[i])<<"\n";
		}
	}
	return 0;
}
2024/7/22 17:25
加载中...