hdu4578

写得头皮发麻。。

本身还是线段树的一些基础操作,只不过是把它们糅合在一起了

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll mod = 10007;
const int N = 100100;

struct Node{
	int l,r;
	ll sum,sum2,sum3;
	int add,mul;
}tree[4*N];
void build(int node,int l,int r){
	tree[node].l=l,tree[node].r=r;
	tree[node].add=0,tree[node].mul=1;
	if (l==r){
		tree[node].sum=tree[node].sum2=tree[node].sum3=0;
		return;
	}
	build(node*2,l,(l+r)/2);
	build(node*2+1,(l+r)/2+1,r);
	tree[node].sum=(tree[node*2].sum+tree[node*2+1].sum)%mod;
	tree[node].sum2=(tree[node*2].sum2+tree[node*2+1].sum2)%mod;
	tree[node].sum3=(tree[node*2].sum3+tree[node*2+1].sum3)%mod;
}
void PushDown(int node){
	if (tree[node].add==0 && tree[node].mul==1)
		return;
 
	tree[node*2].sum3=(tree[node].mul*tree[node].mul%mod*tree[node].mul%mod*tree[node*2].sum3%mod + 3*tree[node].mul*tree[node].mul%mod*tree[node].add%mod*tree[node*2].sum2%mod + 3*tree[node].mul*tree[node].add%mod*tree[node].add%mod*tree[node*2].sum%mod + (tree[node*2].r-tree[node*2].l+1)*tree[node].add%mod*tree[node].add%mod*tree[node].add%mod)%mod;
	tree[node*2].sum2=(tree[node*2].sum2*tree[node].mul%mod*tree[node].mul%mod + 2*tree[node].add*tree[node].mul%mod*tree[node*2].sum%mod + (tree[node*2].r-tree[node*2].l+1)*tree[node].add%mod*tree[node].add%mod)%mod;
	tree[node*2].sum=(tree[node*2].sum*tree[node].mul + tree[node].add*(tree[node*2].r-tree[node*2].l+1)%mod)%mod;
 
	tree[node*2+1].sum3=(tree[node].mul*tree[node].mul%mod*tree[node].mul*tree[node*2+1].sum3%mod + 3*tree[node].mul*tree[node].mul%mod*tree[node].add%mod*tree[node*2+1].sum2%mod + 3*tree[node].mul*tree[node].add%mod*tree[node].add%mod*tree[node*2+1].sum%mod + (tree[node*2+1].r-tree[node*2+1].l+1)*tree[node].add%mod*tree[node].add%mod*tree[node].add%mod)%mod;
	tree[node*2+1].sum2=(tree[node*2+1].sum2*tree[node].mul%mod*tree[node].mul%mod + 2*tree[node].add*tree[node].mul%mod*tree[node*2+1].sum%mod + (tree[node*2+1].r-tree[node*2+1].l+1)*tree[node].add%mod*tree[node].add%mod)%mod;
	tree[node*2+1].sum=(tree[node*2+1].sum*tree[node].mul%mod + tree[node].add*(tree[node*2+1].r-tree[node*2+1].l+1)%mod)%mod;
 
	tree[node*2].mul=(tree[node*2].mul*tree[node].mul)%mod;
	tree[node*2].add=(tree[node*2].add*tree[node].mul%mod+tree[node].add)%mod;
 
	tree[node*2+1].mul=(tree[node*2+1].mul*tree[node].mul)%mod;
	tree[node*2+1].add=(tree[node*2+1].add*tree[node].mul%mod+tree[node].add)%mod;
 
	tree[node].add=0;
	tree[node].mul=1;
}
void Add(int node,int l,int r,int v){
	if (tree[node].l>r || tree[node].r<l)
		return;
	if (l<=tree[node].l && tree[node].r<=r){
		tree[node].sum3=(tree[node].sum3+3*tree[node].sum2%mod*v%mod + 3*tree[node].sum%mod*v%mod*v%mod + (tree[node].r-tree[node].l+1)*v%mod*v%mod*v%mod)%mod;
		tree[node].sum2=(tree[node].sum2+2*tree[node].sum*v%mod+(tree[node].r-tree[node].l+1)*v%mod*v%mod)%mod;
		tree[node].sum=(tree[node].sum+v*(tree[node].r-tree[node].l+1)%mod)%mod;
		tree[node].add=(tree[node].add+v)%mod;
		return;
	}
	if (tree[node].l==tree[node].r)
		return;
	PushDown(node);
	Add(node*2,l,r,v);
	Add(node*2+1,l,r,v);
	tree[node].sum=(tree[node*2].sum+tree[node*2+1].sum)%mod;
	tree[node].sum2=(tree[node*2].sum2+tree[node*2+1].sum2)%mod;
	tree[node].sum3=(tree[node*2].sum3+tree[node*2+1].sum3)%mod;
}
void Mul(int node,int l,int r,int v){
	if (tree[node].l>r || tree[node].r<l)
		return;
	if (l<=tree[node].l && tree[node].r<=r){
		tree[node].sum3=(tree[node].sum3*v%mod*v%mod*v%mod)%mod;
		tree[node].sum2=(tree[node].sum2*v%mod*v)%mod;
		tree[node].sum=(tree[node].sum*v)%mod;
		tree[node].add=(tree[node].add*v)%mod;
		tree[node].mul=(tree[node].mul*v)%mod;
		return;
	}
	if (tree[node].l==tree[node].r)
		return;
	PushDown(node);
	Mul(node*2,l,r,v);
	Mul(node*2+1,l,r,v);
	tree[node].sum=(tree[node*2].sum+tree[node*2+1].sum)%mod;
	tree[node].sum2=(tree[node*2].sum2+tree[node*2+1].sum2)%mod;
	tree[node].sum3=(tree[node*2].sum3+tree[node*2+1].sum3)%mod;
}
void Change(int node,int l,int r,int v){
	if (tree[node].l>r || tree[node].r<l)
		return;
	if (l<=tree[node].l && tree[node].r<=r){
		tree[node].sum3=((tree[node].r-tree[node].l+1)*v%mod*v%mod*v%mod)%mod;
		tree[node].sum2=((tree[node].r-tree[node].l+1)*v%mod*v%mod)%mod;
		tree[node].sum=((tree[node].r-tree[node].l+1)*v)%mod;
		tree[node].add=v%mod;
		tree[node].mul=0;
		return;
	}
	if (tree[node].l==tree[node].r)
		return;
	PushDown(node);
	Change(node*2,l,r,v);
	Change(node*2+1,l,r,v);
	tree[node].sum=(tree[node*2].sum+tree[node*2+1].sum)%mod;
	tree[node].sum2=(tree[node*2].sum2+tree[node*2+1].sum2)%mod;
	tree[node].sum3=(tree[node*2].sum3+tree[node*2+1].sum3)%mod;
}
ll query(int node,int l,int r,int p){
 
	if (tree[node].l==l && tree[node].r==r){
		if (p==1)
			return tree[node].sum;
		if (p==2)
			return tree[node].sum2;
		if (p==3)
			return tree[node].sum3;
	}
	PushDown(node);
	int mid=(tree[node].l+tree[node].r)/2;
	if (r<=mid)
		return query(node*2,l,r,p);
	else if (l>mid)
		return query(node*2+1,l,r,p);
	else
		return (query(node*2,l,mid,p)+query(node*2+1,mid+1,r,p))%mod;
}
int main(){
	int n,m,op,x,y,c,p;
	while (~scanf("%d%d",&n,&m)){
		if (n==0 && m==0) break;
		build(1,1,n);
		while (m--){
			scanf("%d%d%d%d",&op,&x,&y,&c);
			if (op==1)
				Add(1,x,y,c%mod);
			if (op==2)
				Mul(1,x,y,c%mod);
			if (op==3)
				Change(1,x,y,c%mod);
			if (op==4)
				printf("%lld\n",query(1,x,y,c));
		}
	}
 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38759433/article/details/82465824