1. 程式人生 > >線段樹維護區間(平方和,立方和)修改區間(加,賦值,乘)

線段樹維護區間(平方和,立方和)修改區間(加,賦值,乘)

題目地址

/*
* @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",