hdu 4578 Transformation 线段树

http://acm.hdu.edu.cn/showproblem.php?pid=4578

#include <cstdio>
#include <deque>
#include <set>
#include <string>
#include <map>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;
const int maxn = 100005;
const int mod = 10007;
#define ls(p) p<<1
#define rs(p) p<<1|1
struct tree{
	int l,r;
	int sum1;
	int sum2;
	int sum3;
	int col1;
	int col2;
	int col3;
}t[maxn<<2];
int n,m;

int pow2(int p){
	p %= mod;
	return (p*p) % mod;
}
int pow3(int p){
	p %= mod;
	return ((p*p)%mod*p) % mod;
}
void pushup(int p){
	t[p].sum1 = (t[ls(p)].sum1 + t[rs(p)].sum1) % mod;
	t[p].sum2 = (t[ls(p)].sum2 + t[rs(p)].sum2) % mod;
	t[p].sum3 = (t[ls(p)].sum3 + t[rs(p)].sum3) % mod;
}
	
void pushdown(int p){
	if(t[p].col3){
		t[ls(p)].col3 = t[rs(p)].col3 = t[p].col3;
		t[ls(p)].col1 = t[rs(p)].col1 = 0;
		t[ls(p)].col2 = t[rs(p)].col2 = 1;
		t[ls(p)].sum1 = (t[ls(p)].r - t[ls(p)].l + 1) * t[ls(p)].col3 % mod;
		t[ls(p)].sum2 = (t[ls(p)].r - t[ls(p)].l + 1) * pow2(t[ls(p)].col3) % mod;
		t[ls(p)].sum3 = (t[ls(p)].r - t[ls(p)].l + 1) * pow3(t[ls(p)].col3) % mod;
		t[rs(p)].sum1 = (t[rs(p)].r - t[rs(p)].l + 1) * t[rs(p)].col3 % mod;
		t[rs(p)].sum2 = (t[rs(p)].r - t[rs(p)].l + 1) * pow2(t[rs(p)].col3) % mod;
		t[rs(p)].sum3 = (t[rs(p)].r - t[rs(p)].l + 1) * pow3(t[rs(p)].col3) % mod;
		t[p].col3 = 0;
	}
	if(t[p].col1 != 0 || t[p].col2 != 1){
		t[ls(p)].col1 = (t[p].col2 * t[ls(p)].col1 % mod + t[p].col1) % mod;
		t[ls(p)].col2 = t[p].col2 * t[ls(p)].col2 % mod;
		int sum1,sum2,sum3;
        sum1 = (t[ls(p)].sum1*t[p].col2%mod + (t[ls(p)].r - t[ls(p)].l + 1)*t[p].col1%mod)%mod;
        sum2 = (t[p].col2 * t[p].col2 % mod * t[ls(p)].sum2 % mod + 2*t[p].col1*t[p].col2%mod * t[ls(p)].sum1%mod + (t[ls(p)].r - t[ls(p)].l + 1)*t[p].col1%mod*t[p].col1%mod)%mod;
        sum3 = t[p].col2 * t[p].col2 % mod * t[p].col2 % mod * t[ls(p)].sum3 % mod;
        sum3 = (sum3 + 3*t[p].col2 % mod * t[p].col2 % mod * t[p].col1 % mod * t[ls(p)].sum2) % mod;
        sum3 = (sum3 + 3*t[p].col2 % mod * t[p].col1 % mod * t[p].col1 % mod * t[ls(p)].sum1) % mod;
        sum3 = (sum3 + (t[ls(p)].r - t[ls(p)].l + 1)*t[p].col1%mod * t[p].col1 % mod * t[p].col1 % mod) % mod;
        t[ls(p)].sum1 = sum1;
        t[ls(p)].sum2 = sum2;
        t[ls(p)].sum3 = sum3;


        t[rs(p)].col1 = (t[p].col2 * t[rs(p)].col1 % mod + t[p].col1) % mod;
		t[rs(p)].col2 = t[p].col2 * t[rs(p)].col2 % mod;
        sum1 = (t[rs(p)].sum1*t[p].col2%mod + (t[rs(p)].r - t[rs(p)].l + 1)*t[p].col1%mod)%mod;
        sum2 = (t[p].col2 * t[p].col2 % mod * t[rs(p)].sum2 % mod + 2*t[p].col1*t[p].col2%mod * t[rs(p)].sum1%mod + (t[rs(p)].r - t[rs(p)].l + 1)*t[p].col1%mod*t[p].col1%mod)%mod;
        sum3 = t[p].col2 * t[p].col2 % mod * t[p].col2 % mod * t[rs(p)].sum3 % mod;
        sum3 = (sum3 + 3*t[p].col2 % mod * t[p].col2 % mod * t[p].col1 % mod * t[rs(p)].sum2) % mod;
        sum3 = (sum3 + 3*t[p].col2 % mod * t[p].col1 % mod * t[p].col1 % mod * t[rs(p)].sum1) % mod;
        sum3 = (sum3 + (t[rs(p)].r - t[rs(p)].l + 1)*t[p].col1%mod * t[p].col1 % mod * t[p].col1 % mod) % mod;
        t[rs(p)].sum1 = sum1;
        t[rs(p)].sum2 = sum2;
        t[rs(p)].sum3 = sum3;


        t[p].col1 = 0;
        t[p].col2 = 1;
	}
}

void build(int l,int r,int p){
	t[p].l = l;
	t[p].r = r;
	t[p].sum1 = t[p].sum2 = t[p].sum3 = 0;
	t[p].col1 = t[p].col2 = t[p].col3 = 0;
	if(l == r)return;
	int m = (l + r) >> 1;
	build(l,m,ls(p));
	build(m+1,r,rs(p));
}

void update1(int L,int R,int p,int c){
	int l = t[p].l;
	int r = t[p].r;
	if(L<=l && r<=R){
		t[p].col1 += c;
		t[p].col1 %= mod;
		t[p].sum3 = (t[p].sum3 + 3*t[p].sum2%mod*c%mod + 3*t[p].sum1%mod*c%mod*c%mod + (r - l + 1)*c%mod*c%mod*c%mod)%mod;
        t[p].sum2 = (t[p].sum2 + 2*t[p].sum1%mod*c%mod + (r - l + 1)*c%mod*c%mod)%mod;
        t[p].sum1 = (t[p].sum1 + (r - l + 1)*c%mod)%mod;
        return;
	}
	pushdown(p);
	int m = (l + r) >> 1;
	if(L <= m)update1(L,R,ls(p),c);
	if(R > m)update1(L,R,rs(p),c);
	pushup(p);
}

void update2(int L,int R,int p,int c){
	int l = t[p].l;
	int r = t[p].r;
	if(L<=l && r<=R){
		t[p].col1 = t[p].col1*c%mod;
		t[p].col2 = t[p].col2*c%mod;
		t[p].sum3 = t[p].sum3*pow3(c)%mod;
        t[p].sum2 = t[p].sum2*pow2(c)%mod;
        t[p].sum1 = t[p].sum1*c%mod;
        return;
	}
	pushdown(p);
	int m = (l + r) >> 1;
	if(L <= m)update2(L,R,ls(p),c);
	if(R > m)update2(L,R,rs(p),c);
	pushup(p);
}

void update3(int L,int R,int p,int c){
	int l = t[p].l;
	int r = t[p].r;
	if(L<=l && r<=R){
		t[p].col3 = c;
		t[p].col1 = 0;
		t[p].col2 = 1;
		t[p].sum3 = (r-l+1)*pow3(c)%mod;
        t[p].sum2 = (r-l+1)*pow2(c)%mod;
        t[p].sum1 = (r-l+1)*c%mod;
        return;
	}
	pushdown(p);
	int m = (l + r) >> 1;
	if(L <= m)update3(L,R,ls(p),c);
	if(R > m)update3(L,R,rs(p),c);
	pushup(p);
}

int query1(int L, int R,int p){
	int l = t[p].l;
	int r = t[p].r;
	if(L <= l && r <= R){
		return t[p].sum1;
	}
	pushdown(p);
	int m = (l+r) >> 1;
	int ans = 0;
	if(m >= L)ans = (ans + query1(L,R,ls(p)))%mod;
	if(m < R)ans = (ans + query1(L,R,rs(p)))%mod;
	return ans;
}

int query2(int L,int R,int p){
	int l = t[p].l;
	int r = t[p].r;
	if(L <= l && r <= R){
		return t[p].sum2;
	}
	pushdown(p);
	int m = (l+r) >> 1;
	int ans = 0;
	if(m >= L)ans = (ans + query2(L,R,ls(p)))%mod;
	if(m < R)ans = (ans + query2(L,R,rs(p)))%mod;
	return ans;
}

int query3(int L,int R,int p){
	int l = t[p].l;
	int r = t[p].r;
	if(L <= l && r <= R){
		return t[p].sum3;
	}
	pushdown(p);
	int m = (l+r) >> 1;
	int ans = 0;
	if(m >= L)ans = (ans + query3(L,R,ls(p)))%mod;
	if(m < R)ans = (ans + query3(L,R,rs(p)))%mod;
	return ans;
}

int main(){
	while(scanf("%d%d",&n,&m),n||m){
		build(1,n,1);
		while(m --){
			int a,b,c,d;
			scanf("%d%d%d%d",&a,&b,&c,&d);
			if(a == 1){
				update1(b,c,1,d);
			}
			else if(a == 2){
				update2(b,c,1,d);
			}
			else if(a == 3){
				update3(b,c,1,d);
			}
			else if(a == 4){
				int ans;
				if(d == 1){
					ans = query1(b,c,1);
				}
				else if(d == 2){
					ans = query2(b,c,1);
				}
				else if(d == 3){
					ans = query3(b,c,1);
				}
				printf("%d\n",ans);
			}
		}
	}
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值