3 条题解
-
0
这题和区间放射点查高度相似,建议先做上题。
思路
和上一道题很像,只不过加上了求和询问,我们只需在结构体里多定义一个,多写一个pushup函数,其余的就是转化的问题了。
对于一个区间,若对其每一个数进行的操作,总的和就会变为
也就是
$$b\times\sum\limits_{k=i}^{k\leq j}{a_k}+(j-i+1)\times c$$这样一来,就好转化了。
AC代码
#include<bits/stdc++.h> #define lc(p) (p<<1) #define rc(p) (p<<1|1) #define int long long using namespace std; const int N=5e5+10,P=998244353; struct node{int l,r,tag,a,b,s;}tr[N<<2]; int a[N]; void pu(int p){tr[p].s=(tr[lc(p)].s+tr[rc(p)].s)%P;} void pd(int p) { if(tr[p].tag) { tr[lc(p)].s=(tr[lc(p)].s*tr[p].a%P+tr[p].b*(tr[lc(p)].r-tr[lc(p)].l+1)%P)%P; tr[rc(p)].s=(tr[rc(p)].s*tr[p].a%P+tr[p].b*(tr[rc(p)].r-tr[rc(p)].l+1)%P)%P; tr[lc(p)].a=tr[lc(p)].a*tr[p].a%P;tr[rc(p)].a=tr[rc(p)].a*tr[p].a%P; tr[lc(p)].b=(tr[p].a*tr[lc(p)].b%P+tr[p].b)%P; tr[rc(p)].b=(tr[p].a*tr[rc(p)].b%P+tr[p].b)%P; tr[lc(p)].tag=tr[rc(p)].tag=1; tr[p].a=1;tr[p].b=0;tr[p].tag=0; } } void build(int p,int l,int r) { tr[p]={l,r,0,1,0,0}; if(l==r){tr[p].s=a[l]%P;return ;} int mid=l+r>>1; build(lc(p),l,mid);build(rc(p),mid+1,r); pu(p); } void change(int p,int l,int r,int va,int vb) { if(tr[p].r<l||r<tr[p].l)return ; if(l<=tr[p].l&&tr[p].r<=r) { tr[p].s=(tr[p].s*va%P+vb*(tr[p].r-tr[p].l+1)%P)%P; tr[p].a=tr[p].a*va%P;tr[p].b=(tr[p].b*va%P+vb)%P; tr[p].tag=1; return ; } pd(p); change(lc(p),l,r,va,vb);change(rc(p),l,r,va,vb); pu(p); } int query(int p,int l,int r) { if(tr[p].r<l||r<tr[p].l)return 0; if(l<=tr[p].l&&tr[p].r<=r)return tr[p].s; pd(p); return (query(lc(p),l,r)+query(rc(p),l,r))%P; } signed main() { int n,q;scanf("%lld%lld",&n,&q); for(int i=0;i<n;i++)scanf("%lld",&a[i]); build(1,0,n-1); while(q--) { int op,l,r,x,y;scanf("%lld",&op); if(op==0) { scanf("%lld%lld%lld%lld",&l,&r,&x,&y); change(1,l,r-1,x,y); } else { scanf("%lld%lld",&l,&r); printf("%lld\n",(query(1,l,r-1)+P)%P); } } return 0; } -
0
#include<bits/stdc++.h> #define lc(p) (p<<1) #define rc(p) (p<<1|1) using namespace std; typedef long long ll; const int mod=998244353; int n,q,a[500010]; struct N{ ll c,k,b; }tr[2000010]; void pushup(int p){ tr[p].c=(tr[lc(p)].c+tr[rc(p)].c)%mod; } void pushdown(int p,int l,int r){ int mid=(l+r)>>1; tr[lc(p)].c=(tr[lc(p)].c*tr[p].k%mod+tr[p].b*(mid-l+1))%mod; tr[lc(p)].b=(tr[p].k*tr[lc(p)].b%mod+tr[p].b)%mod; tr[lc(p)].k=tr[lc(p)].k*tr[p].k%mod; tr[rc(p)].c=(tr[rc(p)].c*tr[p].k%mod+tr[p].b*(r-mid))%mod; tr[rc(p)].b=(tr[p].k*tr[rc(p)].b%mod+tr[p].b)%mod; tr[rc(p)].k=tr[rc(p)].k*tr[p].k%mod; tr[p].k=1; tr[p].b=0; pushup(p); } void bt(int p,int l,int r){ tr[p]={0,1,0}; if(l==r){ tr[p]={a[l],1,0}; return ; } int mid=(l+r)>>1; bt(lc(p),l,mid); bt(rc(p),mid+1,r); pushup(p); } void change(int p,int l,int r,int x,int y,ll k,ll b){ if(l>=x&&r<=y){ tr[p].c=(tr[p].c*k%mod+b*(r-l+1))%mod; tr[p].b=(tr[p].b*k%mod+b)%mod; tr[p].k=tr[p].k*k%mod; return ; } pushdown(p,l,r); int mid=(l+r)>>1; if(x<=mid)change(lc(p),l,mid,x,y,k,b); if(y>mid)change(rc(p),mid+1,r,x,y,k,b); pushup(p); } ll find(int p,int l,int r,int x,int y){ if(l>=x&&r<=y)return tr[p].c; pushdown(p,l,r); int mid=(l+r)>>1; if(y<=mid)return find(lc(p),l,mid,x,y); else if(x>mid) return find(rc(p),mid+1,r,x,y); return (find(lc(p),l,mid,x,y)+find(rc(p),mid+1,r,x,y))%mod; } int main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>n>>q; for(int i=1;i<=n;i++)cin>>a[i]; bt(1,1,n); while(q--){ int op; cin>>op; if(op==0){ int l,r,k,b; cin>>l>>r>>k>>b; l++; change(1,1,n,l,r,k,b); } else{ int x,y; cin>>x>>y; x++; cout<<find(1,1,n,x,y)<<'\n'; } } return 0; } -
0
#include<bits/stdc++.h> using namespace std; #define int long long const int N=5e5+10,P=998244353; void mod(int &x){x=((x%P)+P)%P;} #define lc(p) (p<<1) #define rc(p) (p<<1|1) struct node{int l,r,s,tag,lazy;}tr[N<<2];int a[N]; void pushup(int p){tr[p].s=tr[lc(p)].s+tr[rc(p)].s;mod(tr[p].s);} void pushdown(int p) { if(tr[p].tag!=1) { tr[lc(p)].s*=tr[p].tag;tr[rc(p)].s*=tr[p].tag; mod(tr[lc(p)].s);mod(tr[rc(p)].s); tr[lc(p)].lazy*=tr[p].tag;tr[rc(p)].lazy*=tr[p].tag; mod(tr[lc(p)].lazy);mod(tr[rc(p)].lazy); tr[lc(p)].tag*=tr[p].tag;tr[rc(p)].tag*=tr[p].tag; mod(tr[lc(p)].tag);mod(tr[rc(p)].tag); tr[p].tag=1; } if(tr[p].lazy) { tr[lc(p)].s+=tr[p].lazy*(tr[lc(p)].r-tr[lc(p)].l+1); tr[rc(p)].s+=tr[p].lazy*(tr[rc(p)].r-tr[rc(p)].l+1); mod(tr[lc(p)].s);mod(tr[rc(p)].s); tr[lc(p)].lazy+=tr[p].lazy;tr[rc(p)].lazy+=tr[p].lazy; mod(tr[lc(p)].lazy);mod(tr[rc(p)].lazy); tr[p].lazy=0; } } void bt(int p,int l,int r) { tr[p]={l,r,0,1,0}; if(l==r){tr[p].s=a[l];return;} int mid=(l+r)>>1; bt(lc(p),l,mid);bt(rc(p),mid+1,r); pushup(p); } void change1(int p,int l,int r,int k) { if(tr[p].l>r||tr[p].r<l)return; if(l<=tr[p].l&&tr[p].r<=r) { tr[p].s*=k;tr[p].tag*=k,tr[p].lazy*=k; mod(tr[p].s);mod(tr[p].tag);mod(tr[p].lazy); return ; } pushdown(p); change1(lc(p),l,r,k);change1(rc(p),l,r,k); pushup(p); } void change2(int p,int l,int r,int k) { if(tr[p].l>r||tr[p].r<l)return; if(l<=tr[p].l&&tr[p].r<=r) { tr[p].s+=k*(tr[p].r-tr[p].l+1);tr[p].lazy+=k; mod(tr[p].s);mod(tr[p].lazy); return ; } pushdown(p); change2(lc(p),l,r,k);change2(rc(p),l,r,k); pushup(p); } int query(int p,int l,int r) { if(tr[p].l>r||tr[p].r<l)return 0; if(l<=tr[p].l&&tr[p].r<=r)return tr[p].s; pushdown(p); int ans=query(lc(p),l,r)+query(rc(p),l,r); mod(ans); return ans; } signed main() { ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); int n,q;cin>>n>>q; for(int i=1;i<=n;i++)cin>>a[i]; bt(1,1,n); while(q--) { int op,l,r,b,c;cin>>op; if(op==0) { cin>>l>>r>>b>>c;l++; change1(1,l,r,b);change2(1,l,r,c); } else { cin>>l>>r;l++; cout<<query(1,l,r)<<'\n'; } } return 0; }
- 1
信息
- ID
- 8129
- 时间
- 1000ms
- 内存
- 1024MiB
- 难度
- 7
- 标签
- 递交数
- 49
- 已通过
- 11
- 上传者