线段树求调
查看原帖
线段树求调
1371790
ljh0727楼主2025/8/29 18:04

码分比较丑,可以过样例但全 wa。

调对必关。

#include<iostream>
#include<cstdio>

#define int long long

#define lp p<<1
#define rp p<<1|1

using namespace std;

const int M=1e5+5;

int a[M],mod;

struct node{
	int l,r,sum;
	int add,mul; 
	void tag(int ak,int mk){
		if(ak!=0){
			add=(add+ak)%mod;
			sum=(sum+(r-l+1)*ak)%mod;
		} 
		if(mk!=1){
			add=(add*mk)%mod;
			sum=(sum*mk)%mod;
			mul=(mul*mk)%mod;
		}
	}
}; 

node tree[M<<2];

void build(int l,int r,int p){ 
	tree[p].l=l;tree[p].r=r;
	tree[p].mul=1;
	if(l==r){
		tree[p].sum=a[l];
		return;
	}
	int mid=l+(r-l)/2;
	build(l,mid,lp);
	build(mid+1,r,rp);
	tree[p].sum=(tree[lp].sum+tree[rp].sum)%mod;
}

void down(int p){
	tree[lp].tag(tree[p].add,tree[p].mul);
	tree[rp].tag(tree[p].add,tree[p].mul);
	tree[p].add=0;
	tree[p].mul=1;
}

void update(int l,int r,int ak,int mk,int p){
	if(tree[p].l==l&&tree[p].r==r){tree[p].tag(ak,mk);return;}
	down(p);
	int mid=(tree[p].l+tree[p].r)>>1;
	if(r<=mid)update(l,r,ak,mk,lp);
	else if(l>mid)update(l,r,ak,mk,rp);
	else{
		update(l,mid,ak,mk,lp);
		update(mid+1,r,ak,mk,rp);
	}
	tree[p].sum=(tree[lp].sum+tree[rp].sum)%mod;
}

int query(int l,int r,int p){
	if(tree[p].l==l&&tree[p].r==r)return tree[p].sum;
	down(p);
	int mid=(tree[p].l+tree[p].r)>>1;
	if(r<=mid)return query(l,r,lp);
	else if(l>mid)return query(l,r,rp);
	else return (query(l,mid,lp)+query(mid+1,r,rp))%mod;
}

signed main(){
	
	int n,q;
	scanf("%lld%lld%lld",&n,&q,&mod);
	
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	} 
	
	build(1,n,1);
	
	while(q--){
		int op,x,y,k;
		scanf("%lld%lld%lld",&op,&x,&y);
		if(op==1){
			scanf("%lld",&k);
			update(x,y,0,k,1);
		}else if(op==2){
			scanf("%lld",&k);
			update(x,y,k,1,1);
		}else{
			printf("%lld\n",query(x,y,1)%mod);
		}
	}
	
	return 0;
}
 
2025/8/29 18:04
加载中...