社区讨论
分块求优化啊,写了80分
P2023[AHOI2009] 维护序列参与者 1已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mi6omvcu
- 此快照首次捕获于
- 2025/11/20 08:17 4 个月前
- 此快照最后确认于
- 2025/11/20 08:17 4 个月前
CPP
// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define int long long
#define maxn 100005
#define maxm 1005
using namespace std;
int n,m,p,blo,a[maxn],d[maxn],len;
int add[maxm],x[maxm],sum[maxn];
void re(int u)
{
int s=min(n,(u)*blo);
sum[u]=0;
for(int i=(u-1)*blo+1;i<=s;i++){
a[i]=a[i]*x[u]+add[u];
a[i]%=p;
sum[u]+=a[i];
}
sum[u]%=p;
add[u]=0;x[u]=1;
}
long long query(int fr,int to)
{
// cout<<fr<<" "<<to<<endl;
int ans=0;
int s=min(to,(d[fr])*blo);
// cout<<s<<" s"<<endl;
re(d[fr]);
for(int i=fr;i<=s;i++){
// cout<<i<<" i"<<endl;
ans+=a[i];
// cout<<ans<<" ans"<<endl;
ans%=p;
}
if(d[fr]!=d[to]){
re(d[to]);
for(int i=(d[to]-1)*blo+1;i<=to;i++){
// cout<<i<<" i"<<endl;
ans+=a[i];
// cout<<ans<<" ans"<<endl;
ans%=p;
}
}
for(int i=d[fr]+1;i<d[to];i++){
// cout<<i<<" ???0"<<endl;
ans+=sum[i]*x[i];
ans%=p;
ans+=add[i]*blo;
ans%=p;
}
return ans;
}
void xx(int fr,int to,int c)
{
int s=min(to,(d[fr])*blo);
re(d[fr]);
for(int i=fr;i<=s;i++){
sum[d[i]]-=a[i];
if(sum[d[i]]<0) sum[d[i]]+=p;
a[i]*=c;
a[i]%=p;
sum[d[i]]+=a[i];
}
sum[d[fr]]%=p;
if(d[fr]!=d[to]){
re(d[to]);
for(int i=(d[to]-1)*blo+1;i<=to;i++){
sum[d[i]]-=a[i];
if(sum[d[i]]<0) sum[d[i]]+=p;
a[i]*=c;
a[i]%=p;
sum[d[i]]+=a[i];
}
sum[d[to]]%=p;
}
for(int i=d[fr]+1;i<d[to];i++){
x[i]*=c;x[i]%=p;
add[i]*=c;add[i]%=p;
}
}
void jiajia(int fr,int to,int c)
{
int s=min(to,(d[fr]*blo));
re(d[fr]);
for(int i=fr;i<=s;i++){
sum[d[i]]-=a[i];
if(sum[d[i]]<0) sum[d[i]]+=p;
a[i]+=c;
a[i]%=p;
sum[d[i]]+=a[i];
}
sum[d[fr]]%=p;
if(d[fr]!=d[to]){
re(d[to]);
for(int i=(d[to]-1)*blo+1;i<=to;i++){
sum[d[i]]-=a[i];
if(sum[d[i]]<0) sum[d[i]]+=p;
a[i]+=c;
a[i]%=p;
sum[d[i]]+=a[i];
}
sum[d[to]]%=p;
}
for(int i=d[fr]+1;i<d[to];i++){
add[i]+=c;add[i]%=p;
}
}
void sc()
{
scanf("%lld%lld",&n,&p);blo=sqrt(n);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]),d[i]=(i-1)/blo+1;
for(int i=1;i<=n;i++) sum[d[i]]+=a[i],x[d[i]]=1,sum[d[i]]%=p;
}
#undef int
int main()
{
sc();
scanf("%lld",&m);
while(m--){
long long opt,fr,to,c;scanf("%lld",&opt);
if(opt==1){
scanf("%lld%lld%lld",&fr,&to,&c);
xx(fr,to,c);
}
if(opt==2){
scanf("%lld%lld%lld",&fr,&to,&c);
jiajia(fr,to,c);
}
if(opt==3){
scanf("%lld%lld",&fr,&to);
printf("%lld\n",query(fr,to));
}
}
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...