线段树维护区间(平方和,立方和)修改区间(加,赋值,乘)

题目地址

/*
* @Author: hannibal
* @Date:   2018-08-07 10:42:26
* @Last Modified by:   hannibal
* @Last Modified time: 2018-08-07 17:08:44
*/
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long  ll;
const ll mod = 10007;
const ll maxn = 1e5+10;
ll Case = 1, n, m;
struct node{
	ll l, r;
	ll add, mul, set;
	ll p1, p2, p3;
	ll mid(){return (l+r)/2;}
}tr[maxn<<2];
void pushup(ll rt) {
	tr[rt].p1 = (tr[rt<<1].p1 + tr[rt<<1|1].p1)%mod;
	tr[rt].p2 = (tr[rt<<1].p2 + tr[rt<<1|1].p2)%mod;
	tr[rt].p3 = (tr[rt<<1].p3 + tr[rt<<1|1].p3)%mod;
}
void caladd(ll rt) {
	ll len1 = (tr[rt<<1].r-tr[rt<<1].l+1)%mod;
	ll len2 =( tr[rt<<1|1].r-tr[rt<<1|1].l+1)%mod;
	tr[rt<<1].add = (tr[rt<<1].add+tr[rt].add%mod);tr[rt<<1|1].add = (tr[rt<<1|1].add+tr[rt].add)%mod;
	ll temp = (tr[rt].add*tr[rt].add%mod)*tr[rt].add%mod;
	tr[rt<<1].p3 =(tr[rt<<1].p3+(temp*len1)%mod+3*tr[rt].add*((tr[rt<<1].p2+tr[rt<<1].p1*tr[rt].add)%mod)%mod)%mod;
	tr[rt<<1|1].p3 = (tr[rt<<1|1].p3+(temp*len2)%mod+3*tr[rt].add*((tr[rt<<1|1].p2+tr[rt<<1|1].p1*tr[rt].add)%mod)%mod)%mod;
	tr[rt<<1].p2 = (tr[rt<<1].p2+(tr[rt].add*tr[rt].add%mod*len1%mod)+2*tr[rt<<1].p1*tr[rt].add%mod)%mod;
	tr[rt<<1|1].p2 = (tr[rt<<1|1].p2+(tr[rt].add*tr[rt].add%mod*len2%mod)+2*tr[rt<<1|1].p1*tr[rt].add%mod)%mod;
	tr[rt<<1].p1 = (tr[rt<<1].p1+len1*tr[rt].add%mod)%mod;
	tr[rt<<1|1].p1 = (tr[rt<<1|1].p1+len2*tr[rt].add%mod)%mod;
	tr[rt].add = 0;
}
void calmul(ll rt) {
	ll x = tr[rt].mul;
	tr[rt<<1].mul = (x*tr[rt<<1].mul)%mod;
	tr[rt<<1|1].mul = (x*tr[rt<<1|1].mul)%mod;
	if(tr[rt<<1].add) tr[rt<<1].add = (tr[rt<<1].add*x)%mod;
	if(tr[rt<<1|1].add) tr[rt<<1|1].add = (tr[rt<<1|1].add*x)%mod;
	ll temp = (x*x)%mod*x%mod;
	tr[rt<<1].p1 = (tr[rt<<1].p1*x)%mod;
	tr[rt<<1|1].p1 = (tr[rt<<1|1].p1*x)%mod;
	tr[rt<<1].p2 = (tr[rt<<1].p2*x%mod*x)%mod;
	tr[rt<<1|1].p2 = (tr[rt<<1|1].p2*x%mod*x)%mod;
	tr[rt<<1].p3 = (tr[rt<<1].p3*temp%mod)%mod;
	tr[rt<<1|1].p3 = (tr[rt<<1|1].p3*temp%mod)%mod;
	tr[rt].mul = 1;
}
void calset(ll rt) {
	ll len1 = (tr[rt<<1].r-tr[rt<<1].l+1)%mod;
	ll len2 = (tr[rt<<1|1].r-tr[rt<<1|1].l+1)%mod;
	tr[rt<<1].set = tr[rt<<1|1].set = tr[rt].set;
	tr[rt<<1].add = tr[rt<<1|1].add = 0;
	tr[rt<<1].mul = tr[rt<<1|1].mul = 1;
	ll temp = (tr[rt].set*tr[rt].set)%mod*tr[rt].set%mod;
	tr[rt<<1].p1 = len1*(tr[rt].set%mod)%mod;
	tr[rt<<1|1].p1 = len2*(tr[rt].set%mod)%mod;
	tr[rt<<1].p2 = len1*(tr[rt].set*tr[rt].set%mod)%mod;
	tr[rt<<1|1].p2 = len2*(tr[rt].set*tr[rt].set%mod)%mod;
	tr[rt<<1].p3 = len1*temp%mod;
	tr[rt<<1|1].p3 = len2*temp%mod;
	tr[rt].set = 0;
}
void pushdown(ll rt) {
	if(tr[rt].set) calset(rt);
	if(tr[rt].mul != 1) calmul(rt);
	if(tr[rt].add) caladd(rt);
}
void build(ll rt, ll l, ll r){
	tr[rt].l = l; tr[rt].r = r;tr[rt].mul = 1;
	tr[rt].add =  tr[rt].set = 0;
	if(l == r) {tr[rt].p1 = tr[rt].p2 = tr[rt].p3 = 0;return;}
	ll mid = tr[rt].mid();
	build(rt<<1, l, mid);build(rt<<1|1, mid+1, r);
	pushup(rt);
}
void update(ll rt, ll l, ll r, ll flag, ll c) {
	if(tr[rt].l == l && tr[rt].r == r) {
		if(flag == 1){
			tr[rt].add += c;
			ll temp = c*c%mod*c%mod*(r-l+1)%mod;
			tr[rt].p3 = (tr[rt].p3+temp+3*c*((tr[rt].p2+tr[rt].p1*c)%mod))%mod;
			tr[rt].p2 = (tr[rt].p2+(c*c%mod*(r-l+1)%mod)+2*tr[rt].p1*c%mod)%mod;
			tr[rt].p1 = (tr[rt].p1+(r-l+1)*c%mod)%mod;
		}
		else if(flag == 2) {
			tr[rt].mul = (tr[rt].mul*c)%mod;
			if(tr[rt].add) tr[rt].add = (tr[rt].add*c)%mod;
			tr[rt].p1 = (tr[rt].p1*c)%mod;
			tr[rt].p2 = (tr[rt].p2*c%mod*c)%mod;
			tr[rt].p3 = (tr[rt].p3*c%mod*c%mod*c)%mod;
		}
		else if(flag == 3) {
			tr[rt].set = c; tr[rt].add = 0; tr[rt].mul = 1;
			tr[rt].p1 = (r-l+1)%mod*c%mod;
			tr[rt].p2 = (r-l+1)%mod*c%mod*c%mod;
			tr[rt].p3 = (r-l+1)%mod*c%mod*c%mod*c%mod;
		}
		return;
	}
	pushdown(rt);
	ll mid = tr[rt].mid();
	if(r <= mid) update(rt<<1, l, r, flag, c);
	else if(l > mid) update(rt<<1|1, l, r, flag, c);
	else update(rt<<1, l, mid, flag, c), update(rt<<1|1, mid+1, r, flag, c);
	pushup(rt);
}
ll query(ll rt, ll l, ll r, ll p) {
	if(tr[rt].l == l && tr[rt].r == r) {
		if(p == 1) return tr[rt].p1%mod;
		else if(p == 2) return tr[rt].p2%mod;
		else return tr[rt].p3%mod;
	}
	pushdown(rt);
	ll mid = tr[rt].mid();
	if(r <= mid) return query(rt<<1, l, r, p);
	else if(l > mid) return query(rt<<1|1, l, r, p);
	else return (query(rt<<1, l, mid, p)+query(rt<<1|1,mid+1, r, p)+mod)%mod;
}
void solve() {
	build(1, 1, n);
	for(ll i = 1; i <= m; i++){
		ll q, x, y, p;
		scanf("%llu%llu%llu%llu", &q, &x, &y, &p);
		if(q == 4) printf("%llu\n", query(1, x, y, p)%mod);
		else update(1, x, y, q, p);
	}
}
int main() {
    ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
    while(scanf("%llu%llu", &n, &m) == 2&&(n+m)) {
        solve();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39921637/article/details/82958664