def rnd():
ret = seed
seed = (seed * 7 + 13) mod1000000007return ret
fori = 1 to n:
a[i] = (rnd() mod vmax) + 1fori = 1 to m:
op = (rnd() mod4) + 1 l = (rnd() mod n) + 1 r = (rnd() mod n) + 1if (l > r):
swap(l, r)
if (op == 3):
x = (rnd() mod (r - l + 1)) + 1else:
x = (rnd() mod vmax) + 1if (op == 4):
y = (rnd() mod vmax) + 1
其中上面的op指题面中提到的四个操作。
【输出格式】
对于每个操作3和4,输出一行仅一个数。
解题思路
珂朵莉树
珂朵莉树是一种优雅的暴力,常用来解决数据随机且带有区间赋值操作的问题
核心思想在于将值相等的区间合并为一个节点保存在 set 中,同时还有一个关键函数 split(x),表示将含有 x 的区间 [l,r] 分为 [l,x−1],[x,r] 两个区间,同时返回后者,所以对于区间 [l,r],可以分为 [split(l),split(r+1)) 这些 set 上的节点,其他操作据此暴力计算或修改即可
注意分区间的时候先 split(r+1) 然后 split(l)
时间复杂度:O(mlog2n)
代码
// Problem: C. Willem, Chtholly and Seniorious// Contest: Codeforces - Codeforces Round #449 (Div. 1)// URL: https://codeforces.com/contest/896/problem/C// Memory Limit: 256 MB// Time Limit: 2000 ms// // Powered by CP Editor (https://cpeditor.org)// %%%Skyqwq#include<bits/stdc++.h>// #define int long long#define help {cin.tie(NULL); cout.tie(NULL);}#define pb push_back#define fi first#define se second#define mkp make_pairusingnamespace std;
typedeflonglong LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
template <typename T> boolchkMax(T &x, T y){ return (y > x) ? x = y, 1 : 0; }
template <typename T> boolchkMin(T &x, T y){ return (y < x) ? x = y, 1 : 0; }
template <typename T> voidinlineread(T &x){
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
constint mod=1e9+7;
int n,m,seed,vmax;
structodt{
int l,r;
mutable LL v;
odt(constint &_l,constint &_r,const LL &_v):l(_l),r(_r),v(_v){}
inlinebooloperator<(const odt &o)const {
return l<o.l;
}
};
set<odt> s;
intrnd(){
int res=seed;
seed=(1ll*seed*7+13)%mod;
return res;
}
autosplit(int x){
auto it=--s.upper_bound({x,0,0});
if(it->l==x)return it;
int l=it->l,r=it->r;
LL v=it->v;
s.erase(it);
s.insert({l,x-1,v});
return s.insert({x,r,v}).fi;
}
voidadd(int l,int r,int x){
auto itr=split(r+1),itl=split(l);
while(itl!=itr)itl->v+=x,itl++;
}
voidassign(int l,int r,int v){
auto itr=split(r+1),itl=split(l);
s.erase(itl,itr);
s.insert({l,r,v});
}
LL ask_kth(int l,int r,int k){
auto itr=split(r+1),itl=split(l);
vector<pair<LL,int>> a;
while(itl!=itr)
{
a.pb({itl->v,itl->r-itl->l+1});
itl++;
}
sort(a.begin(),a.end());
for(auto t:a)
{
k-=t.se;
if(k<=0)return t.fi;
}
return-1;
}
intksm(LL a,int b,int p){
int res=1%p;
a%=p;
while(b)
{
if(b&1)res=1ll*res*a%p;
a=1ll*a*a%p;
b>>=1;
}
return res;
}
intask_sum(int l,int r,int x,int y){
auto itr=split(r+1),itl=split(l);
int res=0;
while(itl!=itr)
{
res=(1ll*res+1ll*ksm(itl->v,x,y)*(itl->r-itl->l+1))%y;
itl++;
}
return res;
}
intmain(){
scanf("%d%d%d%d",&n,&m,&seed,&vmax);
for(int i=1;i<=n;i++)s.insert({i,i,rnd()%vmax+1});
while(m--)
{
int op=rnd()%4+1;
int l=rnd()%n+1,r=rnd()%n+1;
if(l>r)swap(l,r);
int x,y;
if(op==3)x=rnd()%(r-l+1)+1;
else x=rnd()%vmax+1;
if(op==4)
y=rnd()%vmax+1;
if(op==1)add(l,r,x);
elseif(op==2)assign(l,r,x);
elseif(op==3)
printf("%lld\n",ask_kth(l,r,x));
elseprintf("%d\n",ask_sum(l,r,x,y));
}
return0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!