【Ynoi2018】五彩斑斓的世界
【Ynoi2018】五彩斑斓的世界
by AmanoKumiko
Description
给出一个长度为的序列,次操作
每次操作形如
给区间中大于的数减去
询问区间中的出现次数
Input
第一行两个数
第二行个数读入序列
然后行读入操作
Output
每组询问输出一个数表示答案
Sample Input
5 6
1 5 5 5 8
2 2 5 5
1 2 4 3
2 2 5 2
2 2 5 5
1 3 5 1
2 1 5 1
Sample Output
3
3
0
3
Data Constraint
Solution
我们先思考两个朴素的做法
令最大值为
1.暴力扫中的数,减去
当时显然复杂度是错的
2.暴力扫中的数,加上,然后区间减去
当时复杂度是错的
仔细分析,我们的值是单调不降的,
那么只要我们每次都能用一定的时间换取极差减少相应的值,
每个块的复杂度就达到了
换句话说,我们要平衡上面的两种做法
可以发现
当时,第一种做法复杂度,极差减少了
当时,第二种做法复杂度,极差减少了
那么用并查集(第一分块)维护下出现次数就行了
这里还有个问题,空间只有
我们采取一个nb的:逐块处理,这样就解决啦
Code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define N 1000010
#define M 500010
namespace IO{
const int sz=1<<22;
char a[sz+5],b[sz+5],*p1=a,*p2=a,*t=b,p[105];
inline char gc(){
return p1==p2?(p2=(p1=a)+fread(a,1,sz,stdin),p1==p2?EOF:*p1++):*p1++;
}
template<class T>void read(T&x){
x=0;char c=gc();
for(;c<'0'||c>'9';c=gc());
for(;c>='0'&&c<='9';c=gc())x=x*10+(c-'0');
}
inline void flush(){fwrite(b,1,t-b,stdout),t=b;}
inline void pc(char x){*t++=x;if(t-b==sz)flush();}
template<class T>void write(T x,char c='\n'){
if(x==0)pc('0');int t=0;
for(;x;x/=10)p[++t]=x%10+'0';
for(;t;--t)pc(p[t]);pc(c);
}
struct F{~F(){flush();}}f;
}
using IO::read;
using IO::write;
int n,m,a[N],val[N],ans[N],be[N],L[N],R[N],wh[N],fa[N],cnt[N],Mx,tag;
struct node{int op,l,r,x;}q[M];
inline int get(int x){return fa[x]==x?x:(fa[x]=get(fa[x]));}
inline void rebuild(int x){
Mx=tag=0;
fd(i,R[x],L[x])wh[a[i]]=i,cnt[a[i]]=0,val[i]=0;
fo(i,L[x],R[x]){
Mx=max(Mx,a[i]);
cnt[a[i]]++;
fa[i]=wh[a[i]];
if(fa[i]==i)val[i]=a[i];
}
}
inline void clear(int x){
fo(i,L[x],R[x])wh[val[get(i)]]=cnt[val[get(i)]]=0,a[i]=val[get(i)]-tag;
fo(i,L[x],R[x])wh[a[i]]=cnt[a[i]]=0;
}
inline void line(int x,int y){
if(wh[y]){
cnt[y]+=cnt[x];
cnt[x]=0;
fa[wh[x]]=wh[y];
wh[x]=0;
}else{
cnt[y]=cnt[x];
cnt[x]=0;
val[wh[y]=wh[x]]=y;
wh[x]=0;
}
}
int main(){
read(n);read(m);
fo(i,1,n)read(a[i]);
fo(i,1,m)read(q[i].op),read(q[i].l),read(q[i].r),read(q[i].x);
int sz=1300,cs=n/sz+1;
fo(i,1,cs){
L[i]=R[i-1]+1;R[i]=min(L[i]+sz-1,n);
fo(j,L[i],R[i])be[j]=i;
}
fo(i,1,cs){
rebuild(i);
fo(j,1,m){
int le=q[j].l,ri=q[j].r;
le=max(le,L[i]);ri=min(ri,R[i]);
if(le<=ri){
if(q[j].op==1){
if(Mx-tag<=q[j].x)continue;
if(le==L[i]&&ri==R[i]){
if(Mx-tag<=q[j].x*2){
fo(k,q[j].x+tag+1,Mx)if(wh[k])line(k,k-q[j].x);
Mx=min(Mx,q[j].x+tag);
}else{
fo(k,tag+1,tag+q[j].x)if(wh[k])line(k,k+q[j].x);
tag+=q[j].x;
}
}else{
fo(k,L[i],R[i])wh[val[get(k)]]=cnt[val[get(k)]]=0,a[k]=val[get(k)]-tag;
fo(k,le,ri)if(a[k]>q[j].x)a[k]-=q[j].x;
rebuild(i);
}
}else{
if(le==L[i]&&ri==R[i]){
if(wh[q[j].x+tag])ans[j]+=cnt[q[j].x+tag];
}else{
fo(k,le,ri)if(val[get(k)]==q[j].x+tag)ans[j]++;
}
}
}
}
clear(i);
}
fo(i,1,m)if(q[i].op==2)write(ans[i]);
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框架的用法!