Transformation HDU - 4578 完全平方公式和立方公式展开,有点麻烦
Posted qingyuyyyyy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Transformation HDU - 4578 完全平方公式和立方公式展开,有点麻烦相关的知识,希望对你有一定的参考价值。
#include<cstdio> #include<cstring> #include<iostream> #include<math.h> using namespace std; const int mod=10007; const int N=100010; struct Node { int l,r; //和 int sum1; //平方和 int sum2; //立方和 int sum3; //要加的数 int lazy1; //要乘的倍数 int lazy2; //赋值为一个常数 int lazy3; }tr[N*4]; void build(int i,int l,int r) { tr[i].l=l; tr[i].r=r; tr[i].sum1=tr[i].sum2=tr[i].sum3=0; tr[i].lazy1=tr[i].lazy3=0; tr[i].lazy2=1; int mid=l+r>>1; if(l==r) return; build(i<<1,l,mid); build(i<<1|1,mid+1,r); } void pushup(int i) { if(tr[i].l==tr[i].r) return; tr[i].sum1=(tr[i<<1].sum1+tr[(i<<1)|1].sum1)%mod; tr[i].sum2=(tr[i<<1].sum2+tr[(i<<1)|1].sum2)%mod; tr[i].sum3=(tr[i<<1].sum3 + tr[(i<<1)|1].sum3)%mod; } void push_down(int i) { if(tr[i].l==tr[i].r) return; if(tr[i].lazy3!= 0) { tr[i<<1].lazy3=tr[(i<<1)|1].lazy3=tr[i].lazy3; tr[i<<1].lazy1=tr[(i<<1)|1].lazy1=0; tr[i<<1].lazy2=tr[(i<<1)|1].lazy2=1; tr[i<<1].sum1=(tr[i<<1].r-tr[i<<1].l+1)*tr[i<<1].lazy3%mod; tr[i<<1].sum2=(tr[i<<1].r-tr[i<<1].l+1)*tr[i<<1].lazy3%mod*tr[i<<1].lazy3%mod; tr[i<<1].sum3=(tr[i<<1].r-tr[i<<1].l+1)*tr[i<<1].lazy3%mod*tr[i<<1].lazy3%mod*tr[i<<1].lazy3%mod; tr[(i<<1)|1].sum1=(tr[(i<<1)|1].r-tr[(i<<1)|1].l+1)*tr[(i<<1)|1].lazy3%mod; tr[(i<<1)|1].sum2=(tr[(i<<1)|1].r-tr[(i<<1)|1].l+1)*tr[(i<<1)|1].lazy3%mod*tr[(i<<1)|1].lazy3%mod; tr[(i<<1)|1].sum3=(tr[(i<<1)|1].r-tr[(i<<1)|1].l+1)*tr[(i<<1)|1].lazy3%mod*tr[(i<<1)|1].lazy3%mod*tr[(i<<1)|1].lazy3%mod; tr[i].lazy3=0; } //先处理乘,再处理加 if(tr[i].lazy1!=0||tr[i].lazy2!=1) { //加 先乘 再加 tr[i<<1].lazy1=(tr[i].lazy2*tr[i<<1].lazy1%mod+tr[i].lazy1)%mod; //乘 tr[i<<1].lazy2=tr[i<<1].lazy2*tr[i].lazy2%mod; int sum1,sum2,sum3; //左半边 //和 原来的数乘倍数 再加上要加的数*个数 sum1=(tr[i<<1].sum1*tr[i].lazy2%mod + (tr[i<<1].r - tr[i<<1].l + 1)*tr[i].lazy1%mod)%mod; //平方和 乘的倍数的平方*和的平方 2*要加的数*倍数*和 要加的数的平方 //其实就是完全平方公式展开 sum2=(tr[i].lazy2*tr[i].lazy2%mod*tr[i<<1].sum2%mod+2*tr[i].lazy1*tr[i].lazy2%mod * tr[i<<1].sum1%mod + (tr[i<<1].r - tr[i<<1].l + 1)*tr[i].lazy1%mod*tr[i].lazy1%mod)%mod; //立方和 立方公式展开 sum3=tr[i].lazy2 * tr[i].lazy2 % mod * tr[i].lazy2 % mod * tr[i<<1].sum3 % mod; sum3=(sum3 + 3*tr[i].lazy2 % mod * tr[i].lazy2 % mod * tr[i].lazy1 % mod * tr[i<<1].sum2) % mod; sum3=(sum3 + 3*tr[i].lazy2 % mod * tr[i].lazy1 % mod * tr[i].lazy1 % mod * tr[i<<1].sum1) % mod; sum3=(sum3 + (tr[i<<1].r - tr[i<<1].l + 1)*tr[i].lazy1%mod * tr[i].lazy1 % mod * tr[i].lazy1 % mod) % mod; tr[i<<1].sum1 = sum1; tr[i<<1].sum2 = sum2; tr[i<<1].sum3 = sum3; tr[(i<<1)|1].lazy1 = ( tr[i].lazy2*tr[(i<<1)|1].lazy1%mod + tr[i].lazy1 )%mod; tr[(i<<1)|1].lazy2 = tr[(i<<1)|1].lazy2 * tr[i].lazy2 % mod; sum1 = (tr[(i<<1)|1].sum1*tr[i].lazy2%mod + (tr[(i<<1)|1].r - tr[(i<<1)|1].l + 1)*tr[i].lazy1%mod)%mod; sum2 = (tr[i].lazy2 * tr[i].lazy2 % mod * tr[(i<<1)|1].sum2 % mod + 2*tr[i].lazy1*tr[i].lazy2%mod * tr[(i<<1)|1].sum1%mod + (tr[(i<<1)|1].r - tr[(i<<1)|1].l + 1)*tr[i].lazy1%mod*tr[i].lazy1%mod)%mod; sum3 = tr[i].lazy2 * tr[i].lazy2 % mod * tr[i].lazy2 % mod * tr[(i<<1)|1].sum3 % mod; sum3 = (sum3 + 3*tr[i].lazy2 % mod * tr[i].lazy2 % mod * tr[i].lazy1 % mod * tr[(i<<1)|1].sum2) % mod; sum3 = (sum3 + 3*tr[i].lazy2 % mod * tr[i].lazy1 % mod * tr[i].lazy1 % mod * tr[(i<<1)|1].sum1) % mod; sum3 = (sum3 + (tr[(i<<1)|1].r - tr[(i<<1)|1].l + 1)*tr[i].lazy1%mod * tr[i].lazy1 % mod * tr[i].lazy1 % mod) % mod; tr[(i<<1)|1].sum1 = sum1; tr[(i<<1)|1].sum2 = sum2; tr[(i<<1)|1].sum3 = sum3; tr[i].lazy1 = 0; tr[i].lazy2 = 1; } } void update(int i,int l,int r,int type,int c) { if(tr[i].l == l && tr[i].r == r) { c %= mod; if(type == 1) { tr[i].lazy1 += c; tr[i].lazy1 %= mod; tr[i].sum3 = (tr[i].sum3 + 3*tr[i].sum2%mod*c%mod + 3*tr[i].sum1%mod*c%mod*c%mod + (tr[i].r - tr[i].l + 1)*c%mod*c%mod*c%mod)%mod; tr[i].sum2 = (tr[i].sum2 + 2*tr[i].sum1%mod*c%mod + (tr[i].r - tr[i].l + 1)*c%mod*c%mod)%mod; tr[i].sum1 = (tr[i].sum1 + (tr[i].r - tr[i].l + 1)*c%mod)%mod; } else if(type == 2) { tr[i].lazy1 = tr[i].lazy1*c%mod; tr[i].lazy2 = tr[i].lazy2*c%mod; tr[i].sum1 = tr[i].sum1*c%mod; tr[i].sum2 = tr[i].sum2*c%mod*c%mod; tr[i].sum3 = tr[i].sum3*c%mod*c%mod*c%mod; } else { tr[i].lazy1 = 0; tr[i].lazy2 = 1; tr[i].lazy3 = c%mod; tr[i].sum1 = c*(tr[i].r - tr[i].l + 1)%mod; tr[i].sum2 = c*(tr[i].r - tr[i].l + 1)%mod*c%mod; tr[i].sum3 = c*(tr[i].r - tr[i].l + 1)%mod*c%mod*c%mod; } return; } push_down(i); int mid = (tr[i].l + tr[i].r)/2; if(r <= mid) update(i<<1,l,r,type,c); else if(l > mid) update((i<<1)|1,l,r,type,c); else { update(i<<1,l,mid,type,c); update((i<<1)|1,mid+1,r,type,c); } pushup(i); } int query(int i,int l,int r,int p) { if(tr[i].l == l && tr[i].r == r) { if(p == 1) return tr[i].sum1; else if(p== 2) return tr[i].sum2; else return tr[i].sum3; } push_down(i); int mid = (tr[i].l + tr[i].r )/2; if(r <= mid) return query(i<<1,l,r,p); else if(l > mid) return query((i<<1)|1,l,r,p); else return (query(i<<1,l,mid,p)+query((i<<1)|1,mid+1,r,p))%mod; } int main() { int n,m; while(scanf("%d%d",&n,&m) == 2) { if(n == 0 && m == 0) break; build(1,1,n); int type,x,y,c; while(m--) { scanf("%d%d%d%d",&type,&x,&y,&c); if(type == 4) printf("%d ",query(1,x,y,c)); else update(1,x,y,type,c); } } return 0; }
以上是关于Transformation HDU - 4578 完全平方公式和立方公式展开,有点麻烦的主要内容,如果未能解决你的问题,请参考以下文章
30-Transformation(HDU4578)-区间线段树(复杂)