社区讨论
求教大佬,#2#9#10WA到想吐了。。
P3373【模板】线段树 2参与者 3已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mi6tp84f
- 此快照首次捕获于
- 2025/11/20 10:39 4 个月前
- 此快照最后确认于
- 2025/11/20 10:39 4 个月前
CPP
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
long long num[100010],n,k,tree[400040],tag[400040],tag2[400040],p;
void Pushup(long long rt)
{
tree[rt]=tree[rt*2]+tree[rt*2+1];
tree[rt]%=p;
}
void build(long long l,long long r,long long now)
{
if(l==r)
{
tree[now]=num[l];
return;
}
long long m=(l+r)/2;
build(l,m,now*2);
build(m+1,r,now*2+1);
Pushup(now);
}
void up2(int l,int r,int c,int now,bool pls)
{
if(pls){
tree[now]+=c*(r-l+1)%p;
tree[now]%=p;
if(l==r)return;
tag[now]+=c;
tag[now]%=p;
return;
}
else{
tree[now]*=c;
tree[now]%=p;
if(l==r)return;
tag[now]*=c;
tag2[now]*=c;
tag[now]%=p;
tag2[now]%=p;
return;
}
}
void update(long long L,long long R,long long l,long long r,long long c,long long now)
{
long long m=(l+r)/2;
if(tag2[now]!=1){
up2(l,m,tag2[now],now<<1,0);
up2(m+1,r,tag2[now],now<<1|1,0);
tag2[now]=1;
}
if(tag[now]){
up2(l,m,tag[now],now<<1,1);
up2(m+1,r,tag[now],now<<1|1,1);
tag[now]=0;
}
if(L<=l&&r<=R)
{
tree[now]+=c*(r-l+1)%p;
tree[now]%=p;
if(l==r)return;
tag[now]+=c;
tag[now]%=p;
return;
}
if(L <= m) update(L,R,l,m,c,now*2);
if(m < R) update(L,R,m+1,r,c,now*2+1);
Pushup(now);
}
void updateb(long long L,long long R,long long l,long long r,long long c,long long now)
{
long long m=(l+r)/2;
if(tag2[now]!=1){
up2(l,m,tag2[now],now<<1,0);
up2(m+1,r,tag2[now],now<<1|1,0);
tag2[now]=1;
}
if(tag[now]){
up2(l,m,tag[now],now<<1,1);
up2(m+1,r,tag[now],now<<1|1,1);
tag[now]=0;
}
if(L<=l&&r<=R)
{
tree[now]*=c%p;
tree[now]%=p;
if(l==r)return;
tag[now]*=c%p;
tag[now]%=p;
tag2[now]*=c%p;
tag2[now]%=p;
return;
}
if(L <= m) updateb(L,R,l,m,c,now*2);
if(m < R) updateb(L,R,m+1,r,c,now*2+1);
Pushup(now);
}
long long query(long long L,long long R,long long l,long long r,long long now)
{
/*if(tag[now]){
up2(l,m,tag[now],now<<1);
up2(m+1,r,tag[now],now<<1|1);
tree[now]=tree[now<<1]+tree[now<<1|1];
tag[now]=0;
}*/
if(L <= l && R >= r)
{
return tree[now];
}
long long ans=0,m=(l+r)/2;
if(tag2[now]!=1){
up2(l,m,tag2[now],now<<1,0);
up2(m+1,r,tag2[now],now<<1|1,0);
//tree[now]=tree[now<<1]+tree[now<<1|1];
//tree[now]%=p;
tag2[now]=1;
}
if(tag[now]){
up2(l,m,tag[now],now<<1,1);
up2(m+1,r,tag[now],now<<1|1,1);
//tree[now]=tree[now<<1]+tree[now<<1|1];
//tree[now]%=p;
tag[now]=0;
}
if(L <= m) ans+=query(L,R,l,m,now*2);
//ans%=p;
if(R > m) ans+=query(L,R,m+1,r,now*2+1);
return ans;
}
int main()
{
cin >> n >> k >> p;
for(int i = 1;i <=4*n;i++){
tag2[i]=1;
}
for(long long i = 1;i <= n;i++){
scanf("%lld",&num[i]);
}
long long flag=1,a,b,c;
build(1,n,1);
/*for(long long i = 0;i < 20;i++){
cout << tree[i] << ' ';
}
cout << endl;*/
for(long long i = 0;i < k;i++){
cin >> flag;
if(flag==1){
scanf("%lld%lld%lld",&a,&b,&c);
updateb(a,b,1,n,c,1);
/*for(long long i = 0;i < 20;i++){
cout << tree[i] << ' ';
}
cout << endl;*/
}
else if(flag==2){
scanf("%lld%lld%lld",&a,&b,&c);
update(a,b,1,n,c,1);
}
else{
scanf("%lld%lld",&a,&b);
cout << query(a,b,1,n,1)%p << endl;
}
}
/*for(long long i = 0;i < 20;i++){
cout << tree[i] << ' ';
}*/
return 0;
}
代码有点丑...还请大佬原谅
确实不知道该怎么改了
回复
共 2 条回复,欢迎继续交流。
正在加载回复...