样例没过,感觉有问题但是D不出来了QAQ
查看原帖
样例没过,感觉有问题但是D不出来了QAQ
427120
KS_tips_CN楼主2022/7/21 23:28

rt,先放代码

d数组是原数组,t数组是树,add和pls是加法和乘法的lazytag

我感觉在maketag或pushdown函数那里有些问题,但是没有看出来是哪里的问题,希望有神仙可以帮忙调一下QAQ

//------------------------
//Online Judge : Luogu
//By : KS_tips_CN
//Subject : 
//------------------------
//#include<bits/stdc++.h>
//#include<map>
//#include<stack>
//#include<list>
//#include<set>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
#define ll long long
#define reg register int
#define gc getchar()
#define MAXN 100010
#define MOD

using namespace std;
inline ll read( void ) ;

int n,m,mod;
ll t[MAXN*4],d[MAXN],lazy_add[MAXN*4],lazy_pls[MAXN*4];
inline void build( int x , int l , int r ){
	if( l == r ){
		t[x] = d[l];
		t[x] %= mod;
		return ;
	}
	int mid = ( l + r ) >> 1 ;
	build( x*2 , l , mid );
	build( x*2+1 , mid+1 , r );
	t[x] = t[x*2] + t[x*2+1] ;
	t[x] %= mod;
}
//建树
inline bool In_Range( int l , int r , int L , int R ){
	if( L >= l && R <= r ) return 1;//如果右区间在左区间内,返回1 
	return 0;
} 
inline bool Out_Range( int l , int r , int L , int R ){
	if( l > R || r < L ) return 1;
	return 0;
}
inline void make_tag( int x , int l , int r , ll add , ll pls ){
	//如果先推add,那么add在每次下推都会被pls一遍,所以先pls
	if( !lazy_pls[x] ) lazy_pls[x] = 1 ;
	t[x] = ( t[x] * pls ) % mod ; 
	lazy_pls[x] = ( lazy_pls[x] * pls ) % mod ;
	lazy_add[x] = ( lazy_add[x] * pls ) % mod ;
	//修改这个节点的值和这个节点所承受的tag,包括乘法和加法 
	t[x] = ( t[x] + (r-l+1) * add ) % mod ;
	lazy_add[x] = ( lazy_add[x] + add ) % mod ; 
}
inline void pushdown( int x , int l , int r ){
	int mid = ( l + r ) >> 1 ;
	make_tag( x*2 , l , mid , lazy_add[x] , lazy_pls[x] );
	make_tag( x*2+1 , mid+1 , r , lazy_add[x] , lazy_pls[x] );
	lazy_add[x] = 0 ;
	lazy_pls[x] = 1 ;
}
//接下来我们按照正常方法写三个函数,分别是加法,乘法,查询
inline void add( int x , int l , int r , int L , int R , ll num ){
	//当前在序号为x的[l,r]区间    为目标区间[L,R]   加上num
	if( In_Range(L,R,l,r) ) make_tag( x , l , r , num , 1 );
	else {
		if( !Out_Range(L,R,l,r) ){
			pushdown(x,l,r);
			int mid = ( l + r ) >> 1 ;
			add( x*2 , l , mid , L , R , num );
			add( x*2+1 , mid+1 , r , L , R , num );
			t[x] = t[x*2] + t[x*2+1] ;
			t[x] %= mod;
		}
	}
}
inline void plus_( int x , int l , int r , int L , int R , ll num ){
	if( In_Range(L,R,l,r) ) make_tag( x , l , r , 0 , num );
	else {
		if( !Out_Range(L,R,l,r) ){
			pushdown(x,l,r);
			int mid = ( l + r ) >> 1 ;
			plus_( x*2 , l ,mid , L , R , num );
			plus_( x*2+1 , mid+1 , r , L , R , num );
			t[x] = t[x*2] + t[x*2+1] ;
			t[x] %= mod;
		}
	}
}
inline ll search( int x , int l , int r , int L , int R ){
	if( In_Range(L,R,l,r) ) return t[x];
	else if( Out_Range(L,R,l,r) ) return 0;
	else {
		pushdown(x,l,r);
		int mid = ( l + r ) >> 1 ;
		return ( search( x*2 , l , mid , L , R ) + search( x*2+1 , mid+1 , r , L , R ) ) % mod ;
		
	}
}

int main( void ) {

	n = read();// 
	m = read();//操作数量 
	mod = read();//模数 
	for( reg i = 1 ; i <= n ; i++ ) d[i] = read();
	build(1,1,n);
	int a,b,c;
	ll d;
	for( reg i = 1 ; i <= m ; i++ ){
		a = read();
		b = read();
		c = read();
		if( a == 1 ){
			cin >> d ;
			plus_(1,1,n,b,c,d);
		}
		else if( a == 2 ){
			cin >> d ;
			add(1,1,n,b,c,d);
		}
		else {
			cout << search(1,1,n,b,c) << endl ;
		}
	}
	return 0;
}

inline ll read( void ) {
	ll x = 0 , f = 0 ;
   	char ch = gc ;
   	while( !isdigit( ch ) )
    	f |= ( ch == '-' ) , ch = gc ;
   	while( isdigit( ch ) )
    	x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ) , ch = gc ;
    return f ? -x : x ;
}

2022/7/21 23:28
加载中...