3 条题解

  • 0
    @ 2026-8-3 15:51:28

    这题和区间放射点查高度相似,建议先做上题。

    思路

    和上一道题很像,只不过加上了求和询问,我们只需在结构体里多定义一个ss,多写一个pushup函数,其余的就是转化的问题了。

    对于一个区间ai,ai+1,aja_i,a_{i+1},……a_j,若对其每一个数进行×b+c\times b+c的操作,总的和就会变为

    k=ikjb×ak+c\sum\limits_{k=i}^{k\leq j}{b\times a_k+c}

    也就是

    $$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
      @ 2025-12-21 11:11:31
      #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
        @ 2025-12-18 18:49:36
        #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

        区间仿射区间和(Range Affine Range Sum)

        信息

        ID
        8129
        时间
        1000ms
        内存
        1024MiB
        难度
        7
        标签
        递交数
        49
        已通过
        11
        上传者