P3373 线段树2 30分求助!
查看原帖
P3373 线段树2 30分求助!
384064
kevin985楼主2021/6/24 12:32

有路过的帮个忙。谢谢!

#include <bits/stdc++.h>
#include <cstring>
#define INF 0x7f7f7f7f
#define eps 1e-6
#define ll long long
#define ull unsigned long long
#define N 400010
using namespace std;
ll n,m,p;
struct Node{
	ll tag1,tag2,num;
}tree[N];
ll a[N];
inline ll read(){
	ll s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
	return s*w;
}
#define mod(n) (n)%=p//(n)=(n)
#define ls u*2
#define rs u*2+1
#define mid (l+r)/2
inline void print_tree()
{
	puts("tree:");
	ll tot=0,c=0;
	for(ll i=1;i<n*2;i++)
	{
		printf("%d ",tree[i].num);
		tot++;
		if(tot>=pow(2,c))
		{
			tot=0;
			c++;
			printf("\n");
		}
	}
	printf("\n");
}
inline void print_tag1()
{
	puts("tag1:");
	ll tot=0,c=0;
	for(ll i=1;i<n*2;i++)
	{
		printf("%d ",tree[i].tag1);
		tot++;
		if(tot>=pow(2,c))
		{
			tot=0;
			c++;
			printf("\n");
		}
	}
	printf("\n");
}
inline void print_tag2()
{
	puts("tag2:");
	ll tot=0,c=0;
	for(ll i=1;i<n*2;i++)
	{
		printf("%d ",tree[i].tag2);
		tot++;
		if(tot>=pow(2,c))
		{
			tot=0;
			c++;
			printf("\n");
		}
	}
	printf("\n");
}
inline void debug()
{
	print_tree();
	print_tag1();
	print_tag2();
}
inline void build(ll u,ll l,ll r)
{
	tree[u].tag1 = 0;
	tree[u].tag2 = 1;
	if(l == r)
	{
		tree[u].num = a[l]; mod(tree[u].num);
		return;
	}
	build(ls,l,mid);
	build(rs,mid+1,r);
	tree[u].num = (tree[ls].num + tree[rs].num);
	mod(tree[u].num);
}
inline void pushdown(ll u,ll l,ll r)
{
	//num
	tree[ls].num = tree[ls].num * tree[u].tag2 + tree[u].tag1 * (mid-l+1); mod(tree[ls].num);
	tree[rs].num = tree[rs].num * tree[u].tag2 + tree[u].tag1 * (r-mid);   mod(tree[rs].num);
	//tag1
	tree[ls].tag1 = tree[ls].tag1 * tree[u].tag2 + tree[u].tag1; mod(tree[ls].tag1);
	tree[rs].tag1 = tree[rs].tag1 * tree[u].tag2 + tree[u].tag1; mod(tree[ls].tag1);
	//tag2
	tree[ls].tag2 = tree[ls].tag2 * tree[u].tag2; mod(tree[ls].tag2);
	tree[rs].tag2 = tree[rs].tag2 * tree[u].tag2; mod(tree[rs].tag1);
	//复原
	tree[u].tag1 = 0;
	tree[u].tag2 = 1;
	//debug
//	printf("pushdown:");
//	debug();
}
inline void up_add(ll u,ll l,ll r,ll L,ll R,ll k)
{
//	printf("add: u=%d, l=%d, r=%d, L=%d, R=%d, k=%d\n", u, l, r, L, R, k);
	if(r < L || l > R) return;
	if(L <= l && R >= r)
	{
		tree[u].tag1 = tree[u].tag1 + k; mod(tree[u].tag1);
		tree[u].num  = tree[u].num + k * ( r - l + 1); mod(tree[u].num);
		return;
	}
	pushdown(u,l,r);
	up_add(ls,l,mid,L,R,k);
	up_add(rs,mid+1,r,L,R,k);
	tree[u].num = tree[ls].num + tree[rs].num; mod(tree[u].num);
}
inline void up_mul(ll u,ll l,ll r,ll L,ll R,ll k)
{
//	printf("mul: u=%d, l=%d, r=%d, L=%d, R=%d, k=%d\n", u, l, r, L, R, k);
	if(r < L || l > R) return;
	if(L <= l && R >= r)
	{
		tree[u].tag2 *= k; mod(tree[u].tag2);
		tree[u].tag1 = tree[u].tag1 * k; mod(tree[u].tag1);
		tree[u].num  = tree[u].num * k; mod(tree[u].num);
		return;
	}
	pushdown(u,l,r);
	up_mul(ls,l,mid,L,R,k);
	up_mul(rs,mid+1,r,L,R,k);
	tree[u].num = tree[ls].num + tree[rs].num; mod(tree[u].num);
}
inline ll query(ll u,ll l,ll r,ll L,ll R)
{
//	printf("query: u=%d, l=%d, r=%d, L=%d, R=%d\n", u, l, r, L, R);
	if(r < L || l > R)
	{
//		puts("stop");
		return 0;
	}
	if(L <= l && R >= r)
	{
//		puts("return");
		return tree[u].num;
	}
	pushdown(u,l,r);
//	puts("continue");
//	printf("pushdown:");
//	print_tree();
	return (query(ls,l,mid,L,R) + query(rs,mid+1,r,L,R)) % p;
}
inline void init()
{
	n = read(),m = read(),p = read();
	for(ll i=1;i<=n;i++) a[i] = read();
//	puts("build:");
	build(1, 1, n);
//	debug();
}
int main()
{
//	freopen("in1.txt","r",stdin);
	init();
	for(ll i=1;i<=m;i++)
	{
//		printf("m=%d,i=%d\n",m,i);
		ll ms=read(),x=read(),y=read(),k;
		switch(ms)
		{
			case 1:
				k=read();
				up_mul(1,1,n,x,y,k);
				break;
			case 2:
				k=read();
				up_add(1,1,n,x,y,k);
				break;
			case 3:
				printf("%lld\n",query(1,1,n,x,y));
				break;
		}
//		print_tree();
	}
	return 0;
}
2021/6/24 12:32
加载中...