社区讨论
30分可能是什么问题
P3373【模板】线段树 2参与者 7已保存回复 10
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 10 条
- 当前快照
- 1 份
- 快照标识符
- @mi6v2dmm
- 此快照首次捕获于
- 2025/11/20 11:17 4 个月前
- 此快照最后确认于
- 2025/11/20 11:17 4 个月前
过了点1、3、4,其他全部wa了。
上代码(请无视鬼畜的变量名)
建树用的是模拟指针。
CPP#include<bits/stdc++.h>
using namespace std;
#define maxn 100010
int n,m,d,tot;//d是要%的数
long long a[maxn];
struct tree{
long long sum,tag[2];
int l,r,lc,rc;
}t[2*maxn];
void build(int l,int r,int p)
{
t[p].l=l;t[p].r=r;
if(l==r){t[p].sum=a[l]%d;return;}
int mid=(r+l)/2;
t[p].lc=++tot;build(l,mid,tot);
t[p].rc=++tot;build(mid+1,r,tot);
t[p].sum=(t[t[p].lc].sum+t[t[p].rc].sum)%d;
}
void down(int p)
{
if(t[p].tag[0]!=0)
{
t[t[p].lc].sum=(t[t[p].lc].sum*t[p].tag[0])%d;
t[t[p].rc].sum=(t[t[p].rc].sum*t[p].tag[0])%d;
if(t[t[p].lc].tag[0]!=0)
t[t[p].lc].tag[0]=(t[t[p].lc].tag[0]*t[p].tag[0]);
else t[t[p].lc].tag[0]=t[p].tag[0];
if(t[t[p].rc].tag[0]!=0)
t[t[p].rc].tag[0]=(t[t[p].rc].tag[0]*t[p].tag[0]);
else t[t[p].rc].tag[0]=t[p].tag[0];
t[p].tag[0]=0;
}
if(t[p].tag[1]!=0)
{
t[t[p].lc].sum=(t[t[p].lc].sum+(t[p].tag[1]*(t[t[p].lc].r-t[t[p].lc].l+1))%d)%d;
t[t[p].rc].sum=(t[t[p].rc].sum+(t[p].tag[1]*(t[t[p].rc].r-t[t[p].rc].l+1))%d)%d;
t[t[p].lc].tag[1]=(t[t[p].lc].tag[1]+t[p].tag[1])%d;
t[t[p].rc].tag[1]=(t[t[p].rc].tag[1]+t[p].tag[1])%d;
t[p].tag[1]=0;
}
}
long long find(int l,int r,int p)
{
if(l<=t[p].l&&r>=t[p].r)return t[p].sum;
down(p);
int mid=(t[p].l+t[p].r)/2;
long long ans=0;
if(l<=mid)ans+=find(l,r,t[p].lc);
if(r>=mid+1)ans+=find(l,r,t[p].rc);
return ans%d;
}
void change(int p,int l,int r,long long c,int flag)
{
if(l<=t[p].l&&r>=t[p].r)
{
if(flag==1)
{
t[p].sum=(t[p].sum*c)%d;
if(t[p].tag[0]!=0)t[p].tag[0]=(t[p].tag[0]*c)%d;
else t[p].tag[0]=c;
t[p].tag[1]=(t[p].tag[1]*c)%d;
}
else
{
t[p].sum=(t[p].sum+(c*(t[p].r-t[p].l+1))%d)%d;
t[p].tag[1]=(t[p].tag[1]+c)%d;
}
return;
}
//----
down(p);
int mid=(t[p].l+t[p].r)/2;
if(l<=mid)change(t[p].lc,l,r,c,flag);
if(r>=mid+1)change(t[p].rc,l,r,c,flag);
t[p].sum=(t[t[p].lc].sum+t[t[p].rc].sum)%d;
}
int main()
{
scanf("%d%d%d",&n,&m,&d);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
build(1,n,0);
int tip,x,y;long long c;
for(int i=1;i<=m;i++)
{
scanf("%d",&tip);
if(tip==3)
{
scanf("%d%d",&x,&y);
printf("%lld\n",find(x,y,0));
}
else
{
scanf("%d%d%lld",&x,&y,&c);
change(0,x,y,c,tip);
}
}
return 0;
}
回复
共 10 条回复,欢迎继续交流。
正在加载回复...