线段树求助
  • 板块灌水区
  • 楼主うっせぇわ
  • 当前回复6
  • 已保存回复6
  • 发布时间2022/11/21 21:26
  • 上次更新2023/10/27 02:01:14
查看原帖
线段树求助
506475
うっせぇわ楼主2022/11/21 21:26
#include<bits/stdc++.h>
using namespace std;
const int N=200100;
struct node{
    int l,r;
    long long sum,addv,mul;
}tree[N*4];
int n,mod,m;
int w[N];
void eval(int k,int addv,int mul){
    tree[k].addv=(tree[k].addv*mul+addv)%mod;
    tree[k].mul=(tree[k].mul*mul)%mod;
    tree[k].sum=(tree[k].sum*mul+(tree[k].r-tree[k].l+1)*addv)%mod;
}
void pushdown(int k){
    eval(k<<1,tree[k].addv,tree[k].mul);
    eval(k<<1|1,tree[k].addv,tree[k].mul);
    tree[k].addv=0;
    tree[k].mul=1;
}

void pushup(int k){
    tree[k].sum=(tree[k<<1].sum+tree[k<<1|1].sum)%mod;
}

void build(int k,int l,int r){
    tree[k]={l,r,w[r],0,1};
    if(l==r)return ;
    int mid=(l+r)/2;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    pushup(k);
}

void modify(int k,int l,int r,int add,int mul){
    if(tree[k].l>=l&&tree[k].r<=r){
        eval(k,add,mul);
        return ;
    }
    pushdown(k);
    int mid=(tree[k].l+tree[k].r)/2;
    if(l<=mid)modify(k<<1,l,r,add,mul);
    if(r>mid)modify(k<<1|1,l,r,add,mul);
    pushup(k);
}

long long query(int k,int l,int r){
    long long ans=0;
    if(tree[k].l>=l&&tree[k].r<=r){
        return tree[k].sum;
    }
    pushdown(k);
    int mid=(tree[k].l+tree[k].r)/2;
    if(l<=mid)ans=ans+query(k<<1,l,r)%mod;
    if(r>mid)ans=ans+query(k<<1|1,l,r)%mod;
    return ans;
}


int main(){
    scanf("%d%d",&n,&mod);
    for(int i=1;i<=n;i++)scanf("%d", &w[i]);
    build(1,1,n);
    scanf("%d",&m);
    while(m--){
        int t,l,r,d;
        scanf("%d%d%d",&t,&l,&r);
        if(t==1){
            scanf("%d",&d);
            modify(1,l,r,0,d);
    	}else if(t==2){
            scanf("%d",&d);
            modify(1,l,r,d,1);
        }else printf("%d\n",query(1, l, r)%mod);
    }
    return 0;
}

这个是区间加和乘,有没有大佬帮忙看看怎么再在里面塞一个求最值QAQ

2022/11/21 21:26
加载中...