Hdu 4578 Transformation(细节很重要) ★

来源:互联网 发布:网络传播类杂志 编辑:程序博客网 时间:2024/06/07 20:49

题目大意:n个数(初始为0)m个操作,操作类型有4中,操作1把区间的每个数+a,操作2把区间的每个数*a.,操作3把区间的每个数=a,操作4,查询区间每个数p次方的和(1<=p<=3)


对于=更新操作:如果之前有*和+的标记,那可以忽略到*+操作,直接=操作,这个最简单,sum1=val,sum2=val*val,sum3=val*val*val;

对于*+操作:如果之前有=标记,就不能忽略了,所以pushdown优先考略=操作。 *+操作可以一起(a*x+c).

注意:在*操作更新时,要一起更新+操作,因为(x+c)*a;

 然后对于 (ax+c)^3=a^3*x^3+3*a^2*c*x^2+3*a*c^2*x+c^3,也就是root[t].sum3=a^3*root[t].sum3+3*a^2*c*root[t].sum2+3*a*c^2*root[t].sum1+c^3*(root[t].r-roo[t].l+1);

 同理 root[t].sum2=root[t].sum2*a^2+root[t].sum1*c*2+c^2*(root[t].r-root[t].l+1);    oot[t].sum1=root[t].sum1*a+c*(root[t].r-root[t].l+1);

注意:sum3,sum2,sum1在这个操作中的顺序不能变。

注意还要手写pow,以及pushdown操作,好多细节需要考虑

pushdown操作时,遇到mul就要更新pos<<1 和pos<<1|1的mul和lazy,遇到lazy就要更新pos<<1 和pos<<1|1的lazy

细节啊!!!!

#include <set>#include <map>#include <stack>#include <queue>#include <deque>#include <cmath>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF  0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-9#define maxn 100100#define MOD 1000000007const long long mod = 10007;int n,m;long long a[maxn*10];struct node{    int l,r;    long long Max,Min;    long long sum[4],lazy,mul,cover;} tree[maxn*4];long long pow(long long a,int b){    long long ans = 1;    for(int i = 0; i < b; i++)        ans = ans * a % mod;    return ans;}void pushup(int pos){    if(tree[pos].l == tree[pos].r)        return;    for(int i = 1; i < 4; i++)        tree[pos].sum[i] = (tree[pos<<1].sum[i] + tree[pos<<1|1].sum[i])%mod;    //tree[pos].Max = max(tree[pos<<1].Max,tree[pos<<1|1].Max);    //tree[pos].Min = min(tree[pos<<1].Min,tree[pos<<1|1].Min);}void pushdown(int pos){    if(tree[pos].l == tree[pos].r)        return;    if(tree[pos].cover != -1)    {        int l = tree[pos<<1].l,r = tree[pos<<1].r;        tree[pos<<1].lazy = 0;        tree[pos<<1].mul = 1;        tree[pos<<1].cover = tree[pos].cover;        for(int i = 1; i < 4; i++)            tree[pos<<1].sum[i] = (long long)(r-l+1)*(long long)pow(tree[pos].cover,i)%mod;        l = tree[pos<<1|1].l,r = tree[pos<<1|1].r;        tree[pos<<1|1].lazy = 0;        tree[pos<<1|1].mul = 1;        tree[pos<<1|1].cover = tree[pos].cover;        for(int i = 1; i < 4; i++)            tree[pos<<1|1].sum[i] = (long long)(r-l+1)*(long long)pow(tree[pos].cover,i)%mod;        tree[pos].cover = -1;    }    if(tree[pos].mul != 1)    {        tree[pos<<1].mul = (tree[pos<<1].mul * tree[pos].mul)%mod;        tree[pos<<1].lazy = (tree[pos<<1].lazy * tree[pos].mul) % mod;        for(int i = 1; i < 4; i++)            tree[pos<<1].sum[i] = (tree[pos<<1].sum[i] * (long long)pow(tree[pos].mul,i))%mod;        tree[pos<<1|1].mul = (tree[pos<<1|1].mul * tree[pos].mul)%mod;        tree[pos<<1|1].lazy = (tree[pos<<1|1].lazy * tree[pos].mul) % mod;        for(int i = 1; i < 4; i++)            tree[pos<<1|1].sum[i] = (tree[pos<<1|1].sum[i] * (long long)pow(tree[pos].mul,i))%mod;        tree[pos].mul = 1;    }    if(tree[pos].lazy)    {        int l = tree[pos<<1].l,r = tree[pos<<1].r;        long long add = tree[pos].lazy;        tree[pos<<1].lazy = (tree[pos<<1].lazy + tree[pos].lazy)%mod;        tree[pos<<1].sum[3] = (tree[pos<<1].sum[3]+3*tree[pos<<1].sum[1]*add*add+3*tree[pos<<1].sum[2]*add+(long long)(r-l+1)*add*add*add)%mod;        tree[pos<<1].sum[2] = (tree[pos<<1].sum[2]+2*tree[pos<<1].sum[1]*add+(long long)(r-l+1)*add*add)%mod;        tree[pos<<1].sum[1] = (tree[pos<<1].sum[1]+(long long)(r-l+1)*add)%mod;        l = tree[pos<<1|1].l,r = tree[pos<<1|1].r;        tree[pos<<1|1].lazy = (tree[pos<<1|1].lazy + tree[pos].lazy)%mod;        tree[pos<<1|1].sum[3] = (tree[pos<<1|1].sum[3]+3*tree[pos<<1|1].sum[1]*add*add+3*tree[pos<<1|1].sum[2]*add+(long long)(r-l+1)*add*add*add)%mod;        tree[pos<<1|1].sum[2] = (tree[pos<<1|1].sum[2]+2*tree[pos<<1|1].sum[1]*add+(long long)(r-l+1)*add*add)%mod;        tree[pos<<1|1].sum[1] = (tree[pos<<1|1].sum[1]+(long long)(r-l+1)*add)%mod;        tree[pos].lazy = 0;    }}void build(int l,int r,int pos){    tree[pos].l = l;    tree[pos].r = r;    for(int i = 0; i < 4; i++)        tree[pos].sum[i] = 0;    tree[pos].lazy = 0;    tree[pos].mul = 1;    tree[pos].cover = -1;    if(l == r)    {        //scanf("%lld",&tree[pos].sum);        //tree[pos].Max = tree[pos].sum;//        tree[pos].Min = tree[pos].sum;        return;    }    int mid = (l+r)/2;    build(l,mid,pos<<1);    build(mid+1,r,pos<<1|1);    //pushup(pos);}                                                   //建树                                                  //查询操作void update(int l,int r,int pos,long long add,int choose){    add %= mod;    if(choose == 1)    {        if(tree[pos].l == l && tree[pos].r == r)        {            //tree[pos].sum += (r-l+1)*add;            //tree[pos].Max = add;//        tree[pos].Min += add;            tree[pos].sum[3] = (tree[pos].sum[3]+3*tree[pos].sum[1]*add*add+3*tree[pos].sum[2]*add+(long long)(r-l+1)*add*add*add)%mod;            tree[pos].sum[2] = (tree[pos].sum[2]+2*tree[pos].sum[1]*add+(long long)(r-l+1)*add*add)%mod;            tree[pos].sum[1] = (tree[pos].sum[1]+(long long)(r-l+1)*add)%mod;            tree[pos].lazy += add;            tree[pos].lazy %= mod;            return;        }        pushdown(pos);        int mid = (tree[pos].l + tree[pos].r) >> 1;        if(r <= mid)            update(l,r,pos<<1,add,choose);        else if(l > mid)            update(l,r,pos<<1|1,add,choose);        else if(l <= mid && r > mid)        {            update(l,mid,pos<<1,add,choose);            update(mid+1,r,pos<<1|1,add,choose);        }        pushup(pos);    }    else if(choose == 2)    {        if(tree[pos].l == l && tree[pos].r == r)        {            for(int i = 1; i < 4; i++)                tree[pos].sum[i] = (tree[pos].sum[i] * (long long)pow(add,i))%mod;            //tree[pos].Max = add;            //tree[pos].Min += add;            tree[pos].mul = tree[pos].mul * add % mod;            tree[pos].lazy = tree[pos].lazy * add % mod;            return;        }        pushdown(pos);        int mid = (tree[pos].l + tree[pos].r) >> 1;        if(r <= mid)            update(l,r,pos<<1,add,choose);        else if(l > mid)            update(l,r,pos<<1|1,add,choose);        else if(l <= mid && r > mid)        {            update(l,mid,pos<<1,add,choose);            update(mid+1,r,pos<<1|1,add,choose);        }        pushup(pos);    }    else    {        if(tree[pos].l == l && tree[pos].r == r)        {            for(int i = 1; i < 4; i++)                tree[pos].sum[i] = (long long)(r-l+1)*(long long)pow(add,i) % mod;            //tree[pos].Max = add;            //tree[pos].Min += add;            tree[pos].lazy = 0;            tree[pos].mul = 1;            tree[pos].cover = add;            return;        }        pushdown(pos);        int mid = (tree[pos].l + tree[pos].r) >> 1;        if(r <= mid)            update(l,r,pos<<1,add,choose);        else if(l > mid)            update(l,r,pos<<1|1,add,choose);        else if(l <= mid && r > mid)        {            update(l,mid,pos<<1,add,choose);            update(mid+1,r,pos<<1|1,add,choose);        }        pushup(pos);    }}                                         //自上而下更新节点long long query(int l,int r,int pos,int choose){    if(tree[pos].l == l && tree[pos].r == r)        return tree[pos].sum[choose];    pushdown(pos);    int mid = (tree[pos].l+tree[pos].r)>>1;    if(r <= mid)        return query(l,r,pos<<1,choose);    else if(l > mid)        return query(l,r,pos<<1|1,choose);    else        return (query(l,mid,pos<<1,choose) + query(mid+1,r,pos<<1|1,choose))%mod;}int main(){    int t,n,m,C = 1,num = 0;    //scanf("%d",&t);    //freopen("1.txt","r",stdin);    while(scanf("%d%d",&n,&m) && (n+m))    {        build(1,n,1);        //printf("Case %d:\n",C++);        while(m--)        {            int k,x,y,c;            scanf("%d%d%d%d",&k,&x,&y,&c);            if(k == 4)                //a[num++] = query(x,y,1,c)%mod;                printf("%lld\n",query(x,y,1,c)%mod);            else                update(x,y,1,(long long)c,k);        }    }//    freopen("2.txt","r",stdin);//    long long l;//    for(int i = 0; i < num; i++)//    {//        scanf("%lld",&l);//        if(l != a[i])//            printf("%d %d %lld %lld\n",i,b[i],l,a[i]);//    }    return 0;}


0 0
原创粉丝点击