luogu P4117 [Ynoi2018] 五彩斑斓的世界
题面传送门
我们发现这个题的值域小的离谱,于是我们考虑从这上面搞事情。
对于Ynoi通常地考虑分块,每一个块内一样的值缩到一起,对于每一个块来说,如果我们能用次操作使最大值减少,那么复杂度就是正确的。
发现对于的情况,我们直接暴力将大于的值减去复杂度是,将最大值减小是正确的,但是如果,这样暴力复杂度不对。我们考虑反过来,将小于等于的加上,并全局打上减的标记,这样我们同样完成了减小的任务。
这个过程可以用并查集实现,具体的,将某个数加/减可以看作和得到的那个数合并,这样的话并查集维护siz即可。
但是具体实现的时候需要开个并查集,空间撑不下。
但是我们发现一个权值的出现次数和块间是没有贡献的,因此可以对每一个块拆开来计算答案。空间复杂度降到,时间复杂度为
居然跑到了最优解,感动中国。
code:
#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define ll long long
#define db double
#define lb long db
#define N (1000000+5)
#define M (100000+5)
#define K (2500+5)
#define mod 998244353
#define Mod (mod-1)
#define eps (1e-9)
#define ull unsigned ll
#define it iterator
#define Gc() getchar()
#define Me(x,y) memset(x,y,sizeof(x))
#define Mc(x,y) memcpy(x,y,sizeof(x))
#define d(x,y) ((k+1)*(x)+(y))
#define R(n) (1ll*rand()*rand()%(n)+1)
#define Pc(x) putchar(x)
#define LB lower_bound
#define UB upper_bound
#define PB push_back
using namespace std;
int Fr,En,L,R,n,m,k,x,y,z,Ps,fa[M],Ans[N],op[N],X[N],Y[N],Z[N],Si[M],A[N];
I int GF(int x){return fa[x]^x?fa[x]=GF(fa[x]):x;}
struct IO{
static const int S=1<<21;
char buf[S],*p1,*p2;int st[105],Top;
~IO(){clear();}
inline void clear(){fwrite(buf,1,Top,stdout);Top=0;}
inline void pc(const char c){Top==S&&(clear(),0);buf[Top++]=c;}
inline char gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
inline IO&operator >> (char&x){while(x=gc(),x==' '||x=='\n'||x=='\r');return *this;}
template<typename T>inline IO&operator >> (T&x){
x=0;bool f=0;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-') f^=1;ch=gc();}
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=gc();
f?x=-x:0;return *this;
}
inline IO&operator << (const char c){pc(c);return *this;}
template<typename T>inline IO&operator << (T x){
if(x<0) pc('-'),x=-x;
do{st[++st[0]]=x%10,x/=10;}while(x);
while(st[0]) pc('0'+st[st[0]--]);return *this;
}
}fin,fout;
int main(){
freopen("1.in","r",stdin);
int i,j,h;fin>>n>>m;k=max(sqrt(n)*2,1);for(i=1;i<=n;i++) fin>>A[i];for(i=1;i<=m;i++) fin>>op[i]>>X[i]>>Y[i]>>Z[i];
for(i=0;i<=n/k;i++){Fr=max(1,i*k),En=min(n,i*k+k-1);
L=R=1;Ps=0;Me(Si,0);for(j=Fr;j<=En;j++) R=max(R,A[j]),Si[A[j]]++;for(j=L;j<=R;j++) fa[j]=j;for(j=1;j<=m;j++){
if(Y[j]<Fr||X[j]>En) continue;if(op[j]^2){if(Z[j]+Ps>R) continue;
if(X[j]>=Fr&&Y[j]<=En) {for(h=X[j];h<=Y[j];h++) GF(A[h])-Ps>Z[j]&&(Si[GF(A[h])]--,A[h]-=Z[j],Si[GF(A[h])]++);continue;}
if(Y[j]>=Fr&&Y[j]<=En) {for(h=Fr;h<=Y[j];h++) GF(A[h])-Ps>Z[j]&&(Si[GF(A[h])]--,A[h]-=Z[j],Si[GF(A[h])]++);continue;}
if(X[j]>=Fr&&X[j]<=En) {for(h=X[j];h<=En;h++) GF(A[h])-Ps>Z[j]&&(Si[GF(A[h])]--,A[h]-=Z[j],Si[GF(A[h])]++);continue;}
if(Z[j]*2<R-Ps) {for(h=L;h<L+Z[j];h++) Si[h+Z[j]]+=Si[h],fa[h]=h+Z[j],Si[h]=0;L+=Z[j];Ps+=Z[j];}
else{for(h=R;h>Z[j]+Ps;h--) Si[h-Z[j]]+=Si[h],fa[h]=h-Z[j],Si[h]=0;while(R&&!Si[R]) R--;}
}else{
if(X[j]>=Fr&&Y[j]<=En) {for(h=X[j];h<=Y[j];h++) GF(A[h])-Ps==Z[j]&&(Ans[j]++);continue;}
if(X[j]>=Fr&&X[j]<=En) {for(h=X[j];h<=En;h++) GF(A[h])-Ps==Z[j]&&(Ans[j]++);continue;}
if(Y[j]>=Fr&&Y[j]<=En) {for(h=Fr;h<=Y[j];h++) GF(A[h])-Ps==Z[j]&&(Ans[j]++);continue;}if(Z[j]==0) Ans[j]+=Si[0];else Z[j]+Ps<=R&&(Ans[j]+=Si[Z[j]+Ps]);
}
}
} for(i=1;i<=m;i++) op[i]^1&&(fout<<Ans[i]<<'\n',0);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2021-07-10 luogu P3245 [HNOI2016]大数
2021-07-10 luogu P5278 算术天才⑨与等差数列
2021-07-10 2019.7.10 义乌模拟赛 T4 D
2021-07-10 2019.7.10 义乌模拟赛 T3 C
2021-07-10 2019.7.10 义乌模拟赛 T2 B