社区讨论
我打的暴力想拿30分,却WA了,求大佬看一下
P4927[1007] 梦美与线段树参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mi6yafi6
- 此快照首次捕获于
- 2025/11/20 12:48 4 个月前
- 此快照最后确认于
- 2025/11/20 12:48 4 个月前
CPP
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define N 100005
using namespace std;
const long long Mod=998244353;
struct LineTree{
int l,r;
long long sum,lazy;
}a[N*4];
void pushup(int x){
a[x].sum=(a[x<<1].sum+a[x<<1|1].sum)%Mod;
}
void pushdown(int x){
a[x<<1].lazy+=a[x].lazy;
a[x<<1].lazy%=Mod;
a[x<<1|1].lazy+=a[x].lazy;
a[x<<1|1].lazy%=Mod;
a[x<<1].sum+=a[x].lazy*(a[x<<1].r-a[x<<1].l+1);
a[x<<1].sum%=Mod;
a[x<<1|1].sum+=a[x].lazy*(a[x<<1|1].r-a[x<<1|1].l+1);
a[x<<1|1].sum%=Mod;
a[x].lazy=0;
return;
}
void build(int x,int l,int r){
if(l==r){
scanf("%lld",&a[x].sum);
a[x].sum%=Mod;
a[x].l=a[x].r=l;
return;
}
int mid=l+r>>1;
a[x].l=l,a[x].r=r;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
pushup(x);
}
void add(int x,int l,int r,int w){
if(a[x].l>=l&&a[x].r<=r){
a[x].lazy+=w;
a[x].lazy%=Mod;
a[x].sum+=w*(a[x].r-a[x].l+1);
a[x].sum%=Mod;
return;
}
if(a[x].l>r||a[x].r<l)return;
if(a[x].lazy)pushdown(x);
add(x<<1,l,r,w);
add(x<<1|1,l,r,w);
pushup(x);
}
void exgcd(long long a,long long b,long long &x,long long &y){
if(b==0){
x=1,y=0;
return;
}
exgcd(b,a%b,x,y);
long long k=x;x=y,y=k-a/b*y;
return;
}
long long ans;
void query(int x,long long y,long long z){
z+=a[x].sum,z%=Mod;
if(a[x].l==a[x].r){
ans+=z*y,ans%=Mod;
return;
}
if(a[x].lazy)pushdown(x);
long long s,l;
exgcd(a[x].sum,Mod,s,l);
s=(s%Mod+Mod)%Mod;
long long le=a[x<<1].sum*s,ri=a[x<<1|1].sum*s;
le%=Mod,ri%=Mod;
query(x<<1,(y*le)%Mod,z);
query(x<<1|1,(y*ri)%Mod,z);
}
int n,m;
int main(){
scanf("%d%d",&n,&m);
build(1,1,n);
for(int i=1;i<=m;i++){
int x;
scanf("%d",&x);
if(x==1){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(1,a,b,c);
}
else if(x==2){
ans=0;
query(1,1,0);
printf("%lld\n",ans);
}
}
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...