中国珂学院
珂朵莉树是一个可以维护区间x次方和查询的高效数据结构,原理十分暴力。
Willem, Chtholly and Seniorious
#include<bits/stdc++.h>
#define mul(a,b,c) ((a)*(b)%(c))
using namespace std;
typedef long long ll;
typedef pair<int,ll> pil;
ll pow(ll a,ll b,ll m)
{
ll r=1;
for(a%=m; b; a=mul(a,a,m),b>>=1)
if(b&1)r=mul(r,a,m);
return r;
}
struct ChthollyTree:map<int,pil>
{
iterator split(int pos)
{
iterator it=lower_bound(pos);
if(it!=end()&&it->first==pos)return it;
--it;
if(pos>it->second.first)return end();
pair<int,pil> p=*it;
erase(it);
insert(make_pair(p.first,pil(pos-1,p.second.second)));
return insert(make_pair(pos,p.second)).first;
}
void add(int l,int r,ll val)
{
for(iterator b=split(l),e=split(r+1); b!=e; ++b)b->second.second+=val;
}
void set(int l,int r,ll val)
{
erase(split(l),split(r+1)),insert(make_pair(l,pil(r,val)));
}
ll rank(int l,int r,int k)
{
vector<pair<ll,int> > v;
for(iterator b=split(l),e=split(r+1); b!=e; ++b)
v.push_back(make_pair(b->second.second,b->second.first-b->first+1));
sort(v.begin(),v.end());
for(int i=0; i<v.size(); ++i)
if(k-=v[i].second,k<=0)return v[i].first;
return -1;
}
ll sum(int l,int r,ll ex,ll m)
{
ll res=0;
for(iterator b=split(l),e=split(r+1); b!=e; ++b)
res=(res+mul(b->second.first-b->first+1,pow(b->second.second,ex,m),m))%m;
return res;
}
} t;
ll n,m,seed,vmax,M=1e9+7;
ll rnd()
{
ll ret=seed;
seed=(seed*7+13)%M;
return ret;
}
int main()
{
scanf("%lld%lld%lld%lld",&n,&m,&seed,&vmax);
for(int i=1; i<=n; ++i)
t.insert(make_pair(i,pil(i,rnd()%vmax+1)));
for(int i=1; i<=m; ++i)
{
int op=rnd()%4+1,l=rnd()%n+1,r=rnd()%n+1;
if(l>r)swap(l,r);
ll x=rnd()%(op==3?r-l+1:vmax)+1;
if(op==1)t.add(l,r,x);
if(op==2)t.set(l,r,x);
if(op==3)printf("%lld\n",t.rank(l,r,x));
if(op==4)printf("%lld\n",t.sum(l,r,x,rnd()%vmax+1));
}
}
脑洞治疗仪
#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef pair<int,ll> pil;
struct ChthollyTree:map<int,pil>
{
iterator split(int pos)
{
iterator it=lower_bound(pos);
if(it!=end()&&it->first==pos)return it;
--it;
if(pos>it->second.first)return end();
pair<int,pil> p=*it;
erase(it);
insert(make_pair(p.first,pil(pos-1,p.second.second)));
return insert(make_pair(pos,p.second)).first;
}
void set(int l,int r,ll val)
{
erase(split(l),split(r+1)),insert(make_pair(l,pil(r,val)));
}
void scure(int l,int r,int x,int y)
{
iterator e=split(r+1),b=split(l),it=b;
int sum=0;
for(; b!=e; ++b)
if(b->second.second)
sum+=b->second.first-b->first+1;
erase(it,e);
insert(make_pair(l,pil(r,0)));
if(!sum)return;
e=split(y+1),b=split(x),it=b;
if(sum>=y-x+1)
{
erase(b,e);
insert(make_pair(x,pil(y,1)));
return;
}
for( ; b!=e; ++b)
if(!b->second.second)
{
sum-=b->second.first-b->first+1;
if(sum<0)return set(b->first,b->second.first+sum,1);
b->second.second=1;
}
}
ll MAX(int l,int r)
{
iterator e=split(r+1),b=split(l);
ll res=0,now=0;
for(; b!=e; ++b)
if(!b->second.second)
now+=b->second.first-b->first+1;
else if(now)res=max(res,now),now=0;
return max(res,now);
}
} t;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
t.insert(make_pair(1,pil(n,1)));
for(int op,l,r,x,y; m--;)
{
scanf("%d%d%d",&op,&l,&r);
if(op==0)t.set(l,r,0);
else if(op==1)scanf("%d%d",&x,&y),t.scure(l,r,x,y);
else printf("%d\n",t.MAX(l,r));
}
}