线段树,30pts,求调
  • 板块题目总版
  • 楼主Zelensky
  • 当前回复5
  • 已保存回复5
  • 发布时间2022/10/11 09:35
  • 上次更新2023/10/27 07:55:30
查看原帖
线段树,30pts,求调
649611
Zelensky楼主2022/10/11 09:35
#include<bits/stdc++.h>
#define int long long
using namespace std;
struct ccc{
    int l,r,laz,pre,ta;
}tree[100000*4+100];
int a[1000000],p;
void build(int i,int le,int ri){
    tree[i].l=le,tree[i].r=ri,tree[i].ta=1;
    if(le==ri){
        tree[i].pre=a[le];
        return ;
    }
    int mid=(le+ri)>>1;
    build(i*2,le,mid);
    build(i*2+1,mid+1,ri);
    tree[i].pre=(tree[i*2].pre+tree[i*2+1].pre);
}
void tag(int i){
        tree[i*2].pre=(tree[i].ta*tree[i*2].pre+tree[i].laz*(tree[i*2].r-tree[i*2].l+1))%p;
        tree[i*2+1].pre=(tree[i].ta*tree[i*2+1].pre+tree[i].laz*(tree[i*2+1].r-tree[i*2+1].l+1))%p;
        tree[i*2].laz=(tree[i].ta*tree[i*2].laz+tree[i].laz)%p;
        tree[i*2+1].laz=(tree[i].ta*tree[i*2+1].laz+tree[i].laz)%p;
        tree[i*2].ta*=tree[i].ta%p;
        tree[i*2+1].ta*=tree[i].ta%p;
        tree[i].laz=0,tree[i].ta=1;
}
void change_mu(int i,int x,int y,int z){
	if(x<=tree[i].l&&y>=tree[i].r){
		tree[i].laz=tree[i].laz%p*z%p;
		tree[i].ta=tree[i].ta%p*z%p;
		tree[i].pre=tree[i].pre%p*z%p;
		return ;
	}
	tag(i);
	int mid=(tree[i].l+tree[i].r)>>1;
	if(x<=mid) change_mu(i*2,x,y,z);
	if(y>mid) change_mu(i*2+1,x,y,z);
	tree[i].pre=(tree[i*2].pre+tree[i*2+1].pre);
}
void change_add(int i,int x,int y,int z){
    if(x<=tree[i].l&&y>=tree[i].r){
        tree[i].pre=(tree[i].pre+z*(tree[i].r-tree[i].l+1))%p;
        tree[i].laz=(tree[i].laz+z)%p;
        return ;
    }
    tag(i);
    int mid=(tree[i].l+tree[i].r)>>1;
    if(x<=mid) change_add(i*2,x,y,z);
    if(y>mid) change_add(i*2+1,x,y,z);
    tree[i].pre=(tree[i*2].pre+tree[i*2+1].pre)%p;
}
int get(int i,int x,int y){
    int ans=0;
    if(x<=tree[i].l&&y>=tree[i].r){
        return tree[i].pre;
    }
    tag(i);
    int mid=(tree[i].l+tree[i].r)>>1;
    if(x<=mid) ans=(ans+get(i*2,x,y))%p;
    if(y>mid) ans=(ans+get(i*2+1,x,y))%p;
    return ans; 
}
signed main(){
    int n,m;
    cin>>n>>m>>p;
    for(int i=1;i<=n;i++)cin>>a[i];
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int opt;
        cin>>opt;
        if(opt==1){
            int x,y,z;
            cin>>x>>y>>z;
            change_mu(1,x,y,z);
        }
        else if(opt==2){
            int x,y,z;
            cin>>x>>y>>z;
            change_add(1,x,y,z);
        }
        else{
        	int x,y;
        	cin>>x>>y;
        	cout<<get(1,x,y)%p<<endl;
        }
    }
    return 0;
}

记录

2022/10/11 09:35
加载中...