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\n",query(1,x,y,c));
            else 
                update(1,x,y,type,c);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/QingyuYYYYY/p/12294832.html