题解 P7334【[JRKSJ R1] 吊打】
题意
给出 表示长为 的序列 , 次操作,支持两种操作:
1 l r
,对所有 ,将 。2 l r
,对所有 ,将 。
最后输出 。
时间 1s,。
思路
:重构全文。
发现区间开方直接拍一个分块上去,参考 P4145。
这里不好维护原数,考虑维护 位置上的数被平方的次数 。
操作 为区间加。考虑操作 ,散块暴力,整块维护 最小值。若 ,直接打区间减 ,否则若 ,跳过,否则暴力开方或将 减一。
由势能分析,我们知道这部分是 的。
求出 后考虑得出答案,用欧拉定理降幂,预处理一下 ,即可在 时间内求出 ,总时间复杂度为 ,期望得分 分。
我没写代码, 写了:
#include<bits/stdc++.h>
using namespace std;
const int mx=2e5+5;
const int mod=998244353;
int a[mx];
int bl[mx],fl[mx],fr[mx];
int s[mx],tag[mx],mn[mx],os[mx];
int pow2[mx];
int n,b,ks;
void init()
{
int i,j,k,mx;
b=sqrt(n);
for(i=1;i-1+b<=n;i+=b)
fl[++ks]=i,fr[ks]=i-1+b;
if(i<=n)
fl[++ks]=i,fr[ks]=n;
for(i=1;i<=ks;i++)
for(j=fl[i];j<=fr[i];j++)
bl[j]=i;
}
int qpow(int a,int p,int mod)
{
if(p==0) return 1;
if(p==1) return a;
long long t=qpow(a,p/2,mod);
return t*t%mod*qpow(a,p%2,mod)%mod;
}
int read()
{
int s=0;
char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s;
}
void cg(int x)
{
mn[x]=2e9;
for(int i=fl[x];i<=fr[x];i++)
mn[x]=min(mn[x],s[i]+tag[x]);
}
void zk(int x)
{
for(int i=fl[x];i<=fr[x];i++)
s[i]+=tag[x];
tag[x]=0;
}
void add(int l,int r)
{
if(bl[l]==bl[r])
{
zk(bl[l]);
for(;l<=r;l++)
s[l]++;
cg(bl[l-1]);
return;
}
add(l,fr[bl[l]]),add(fl[bl[r]],r);
int i;
for(i=bl[l]+1;i<bl[r];i++)
tag[i]++,mn[i]++;
}
void sqrt(int l,int r)
{
if(bl[l]==bl[r])
{
zk(bl[l]);
for(;l<=r;l++)
{
if(a[l]==1) continue;
if(s[l]==0)
{
a[l]=sqrt(a[l]);
os[bl[l]]+=a[l]==1;
}
else s[l]--;
}
cg(bl[l-1]);
return;
}
sqrt(l,fr[bl[l]]),sqrt(fl[bl[r]],r);
for(int i=bl[l]+1;i<bl[r];i++)
{
if(os[i]==fr[i]-fl[i]+1) continue;
if(mn[i]==0)
sqrt(fl[i],fr[i]);
else
mn[i]--,tag[i]--;
}
}
int main()
{
int m,i,opt,l,r,sum=0,wz=2e9,qwq;
n=read(),m=read();
init();
pow2[0]=1;
for(i=1;i<=n;i++)
a[i]=read();
for(i=1;i<=m;i++)
{
pow2[i]=pow2[i-1]*2;
if(pow2[i]>=mod-1&&wz==2e9) wz=i;
pow2[i]%=mod-1;
}
while(m--)
{
opt=read(),l=read(),r=read();
if(opt==1) sqrt(l,r);
else add(l,r);
}
for(i=1;i<=ks;i++)
zk(i);
for(i=1;i<=n;i++)
{
if(a[i]==1)
{
sum=(sum+1)%mod;
continue;
}
qwq=pow2[s[i]];
if(s[i]>=wz) qwq+=mod-1;
sum=(sum+qpow(a[i],qwq,mod))%mod;
}
cout<<sum%mod;
}
再见 qwq~
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话