『Solution』未来日记
未来日记
纪念第一道自己独立想出Solution的Ynoi
题意:支持区间定值修改和区间第
显然1e5
是分块,考虑怎么做
区间定值修改,做过这个的人都知道使用冰茶姬和桶来支持
但显然,这题桶无法满足我们的需求,求第
这里前两个一看就是废物,值域分块貌似有优化的空间?
那么考虑使用值域分块来优化,一看lxl开的
所以说,这时候就涉及到怎么搞的问题了
首先对于区间定值修改,整块直接把siz
,把其有的数插入到
对于散块先暴力重构然后修改(冰茶姬归零)
再次对于区间第
值域分块使得我们只需要快速地知道某个数出现次数就可以找
总的做法:
按照套路:设
显然可以递推求解,复制前一个复杂度
再考虑询问:对于这个块,可以先将散块开个桶统计,复杂度
最后考虑修改怎么搞:我们以块内此数字第一次出现的位置的下标为代表元
设
则
散块直接按照这个式子还原原序列然后暴力修改重构,并重新统计
对于整块,设当前第
-
区间没有
:跳过 -
区间有
没 ,则 -
有
还有 ,非常麻烦,看上去只能暴力重构,事实上这是正确的。Why?容易发现,每一个块进行某次操作,出现这种情况,会使得其维护值的个数少一。有操作2的存在,我们可以发现,维护值的个数是单调不增的,所以操作三实际上每个块只会执行
次,总复杂度 ,每个块的复杂度总和是 级的。
这里我们忽视了一个问题:
事实上,在块的后移的时候用变量tmp
维护即可。
坑人的是:经过bdfs,我知道了,分块块长350,值域块块长317才能跑过……
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
#define N 105500
#define re register
#define S 375
int V=100000;
inline void read(int &x){
x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
}
int n,m,siz,a[N],tot,tt[N],L[S],R[S],pos_v[N],cnt1[S],cnt2[N],cnt[S][N],scnt[S][N],sum[S][S],f[N],sit[S][N],block,len_v=317;
inline int find(int x){
return x==f[x]?x:f[x]=find(f[x]);
}
inline int get(int x){
return (x+block-1)/block;
}
inline void build(int id,int l,int r,int x,int y){
re int tmp=0;
tot=0;
sit[id][x]=sit[id][y]=0;
for(re int i=L[id];i<=R[id];i++){
a[i]=a[find(i)];
if(a[i]==x||a[i]==y)tt[++tot]=i;
}
for(re int i=l;i<=r;i++)if(a[i]==x)a[i]=y,tmp++;
cnt[id][x]-=tmp,cnt[id][y]+=tmp;
for(re int i=1;i<=tot;i++)f[tt[i]]=tt[i];
for(re int i=1;i<=tot;i++){
if(!sit[id][a[tt[i]]])sit[id][a[tt[i]]]=tt[i];
else f[tt[i]]=sit[id][a[tt[i]]];
}
for(int i=id;i<=siz;i++){
scnt[i][x]-=tmp,scnt[i][y]+=tmp;
if(pos_v[x]!=pos_v[y])sum[i][pos_v[x]]-=tmp,sum[i][pos_v[y]]+=tmp;
}
}
inline void change(int l,int r,int x,int y){
re int lpos=get(l),rpos=get(r);
if(lpos==rpos)build(lpos,l,r,x,y);
else {
build(lpos,l,R[lpos],x,y);
build(rpos,L[rpos],r,x,y);
int tmp=0;
for(re int i=lpos+1;i<rpos;i++){
if(sit[i][x]){
if(!sit[i][y])sit[i][y]=sit[i][x],a[sit[i][x]]=y;
else f[sit[i][x]]=sit[i][y];
sit[i][x]=0,tmp+=cnt[i][x],cnt[i][y]+=cnt[i][x],cnt[i][x]=0;
}
scnt[i][x]-=tmp,scnt[i][y]+=tmp;
if(pos_v[x]!=pos_v[y])sum[i][pos_v[x]]-=tmp,sum[i][pos_v[y]]+=tmp;
}
for(re int i=rpos;i<=siz;i++){
scnt[i][x]-=tmp,scnt[i][y]+=tmp;
if(pos_v[x]!=pos_v[y])sum[i][pos_v[x]]-=tmp,sum[i][pos_v[y]]+=tmp;
}
}
}
inline int query(int l,int r,int k){
re int lpos=get(l),rpos=get(r),cnt=0;
if(lpos==rpos){
for(re int i=l;i<=r;i++)a[i]=a[find(i)],cnt1[pos_v[a[i]]]++,cnt2[a[i]]++;
for(re int i=1;i<=len_v;i++){
cnt+=cnt1[i];
if(cnt>=k){
cnt-=cnt1[i];
for(re int j=(i-1)*len_v+1;j<=i*len_v;j++){
cnt+=cnt2[j];
if(cnt>=k){
for(re int i=l;i<=r;i++)cnt2[a[i]]--,cnt1[pos_v[a[i]]]--;
return j;
}
}
}
}
}
else {
for(re int i=l;i<=R[lpos];i++)a[i]=a[find(i)],cnt1[pos_v[a[i]]]++,cnt2[a[i]]++;
for(re int i=L[rpos];i<=r;i++)a[i]=a[find(i)],cnt1[pos_v[a[i]]]++,cnt2[a[i]]++;
for(re int i=1;i<=len_v;i++){
cnt+=cnt1[i]+sum[rpos-1][i]-sum[lpos][i];
if(cnt>=k){
cnt-=cnt1[i]+sum[rpos-1][i]-sum[lpos][i];
for(re int j=(i-1)*len_v+1;j<=i*len_v;j++){
cnt+=cnt2[j]+scnt[rpos-1][j]-scnt[lpos][j];
if(cnt>=k){
for(re int i=l;i<=R[lpos];i++)cnt1[pos_v[a[i]]]--,cnt2[a[i]]--;
for(re int i=L[rpos];i<=r;i++)cnt1[pos_v[a[i]]]--,cnt2[a[i]]--;
return j;
}
}
}
}
}
}
int main() {
read(n);read(m);
for(re int i=1;i<=n;i++){
read(a[i]);f[i]=i;
}
block=350,siz=(n+block-1)/block;
for(re int i=1;i<=V;i++)pos_v[i]=(i-1)/len_v+1;
for(re int i=1;i<=siz;i++){
L[i]=R[i-1]+1,R[i]=min(L[i]+block-1,n);
for(re int j=L[i];j<=R[i];j++){
if(!sit[i][a[j]])sit[i][a[j]]=j;
else f[j]=sit[i][a[j]];
cnt[i][a[j]]++;
}
}
for(re int i=1;i<=siz;i++){
for(re int j=1;j<=len_v;j++)sum[i][j]=sum[i-1][j];
for(re int j=L[i];j<=R[i];j++)sum[i][pos_v[a[j]]]++;
for(re int j=1;j<=V;j++)scnt[i][j]=scnt[i-1][j]+cnt[i][j];
}
while(m--){
re int opt,x,y,l,r,k;
read(opt);
if(opt==1){
read(l),read(r),read(x),read(y);
if(x==y)continue;//114514
change(l,r,x,y);
}
else {
read(l),read(r),read(k);
printf("%d\n",query(l,r,k));
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!