HDU P4578 Transformation

Problem Description
Yuanfang is puzzled with the question below:
There are n integers, a1, a2, …, an. The initial values of them are 0. There are four kinds of operations.
Operation 1: Add c to each number between ax and ay inclusive. In other words, do transformation ak<---ak+c, k = x,x+1,…,y.
Operation 2: Multiply c to each number between ax and ay inclusive. In other words, do transformation ak<---ak×c, k = x,x+1,…,y.
Operation 3: Change the numbers between ax and ay to c, inclusive. In other words, do transformation ak<---c, k = x,x+1,…,y.
Operation 4: Get the sum of p power among the numbers between ax and ay inclusive. In other words, get the result of axp+ax+1p+…+ay p.
Yuanfang has no idea of how to do it. So he wants to ask you to help him. 
                                                         --by HDUoj
http://acm.hdu.edu.cn/showproblem.php?pid=4578


因为p<4,所以,直接线段树维护区间和,平方和,立方和,三棵树,打上乘法,加法,更改标记,注意down的顺序;
所以,会线段树的话,这题主要考代码能力......和信仰。
记得及时取模。
代码如下:
  1 #include<cstdio>
  2 #define mod 10007
  3 using namespace std;
  4 
  5 long long tree[4][400000];
  6 long long mark1[400000],mark2[400000],mark3[400000];
  7 
  8 int n,m,L,R;
  9 long long a,b;
 10 
 11 void work();
 12 void build(int ,int ,int );
 13 void up(int );
 14 void down(int ,int ,int );
 15 void change(int ,int ,int );
 16 long long sum(int ,int ,int );
 17 
 18 int main()
 19 {
 20     while(1)
 21     {
 22         scanf("%d%d",&n,&m);
 23         if(n==0&&m==0)
 24             return 0;
 25         work();
 26     }
 27 }
 28 
 29 void work()
 30 {
 31     int i;
 32     long long ans=0;
 33     build(1,n,1);
 34     for(i=1;i<=m;i++)
 35     {
 36         scanf("%d%d%d%d",&b,&L,&R,&a);
 37         if(b==4)
 38         {
 39                 ans=sum(1,n,1);
 40                 printf("%lld
",ans%mod);
 41         }
 42         else
 43             change(1,n,1);
 44     }
 45 }
 46 
 47 void build(int l,int r,int nu)
 48 {
 49     tree[1][nu]=tree[2][nu]=tree[3][nu]=mark1[nu]=mark3[nu]=0;
 50     mark2[nu]=1;
 51     if(l==r)
 52         return ;
 53     int mid=(l+r)>>1;
 54     build(l,mid,nu<<1);
 55     build(mid+1,r,nu<<1|1);
 56 }
 57 
 58 void up(int nu)
 59 {
 60     tree[1][nu]=(tree[1][nu<<1]+tree[1][nu<<1|1])%mod;
 61     tree[2][nu]=(tree[2][nu<<1]+tree[2][nu<<1|1])%mod;
 62     tree[3][nu]=(tree[3][nu<<1]+tree[3][nu<<1|1])%mod;
 63 }
 64 
 65 void down(int l,int r,int nu)
 66 {
 67     int mid=(l+r)>>1;
 68     if(mark3[nu])
 69     {
 70         tree[1][nu<<1]=tree[2][nu<<1]=tree[3][nu<<1]=0;
 71         mark1[nu<<1]=0;mark2[nu<<1]=1;
 72         mark3[nu<<1]=mark3[nu];
 73         tree[1][nu<<1|1]=tree[2][nu<<1|1]=tree[3][nu<<1|1]=0;
 74         mark1[nu<<1|1]=0;mark2[nu<<1|1]=1;
 75         mark3[nu<<1|1]=mark3[nu];
 76     }
 77     tree[3][nu<<1]=(tree[3][nu<<1]*mark2[nu]*mark2[nu]*mark2[nu])%mod;
 78     tree[2][nu<<1]=(tree[2][nu<<1]*mark2[nu]*mark2[nu])%mod;
 79     tree[1][nu<<1]=(tree[1][nu<<1]*mark2[nu])%mod;
 80     tree[3][nu<<1]=(tree[3][nu<<1]+3*tree[2][nu<<1]*mark1[nu]+3*tree[1][nu<<1]*mark1[nu]*mark1[nu]+(mid-l+1)*mark1[nu]*mark1[nu]*mark1[nu])%mod;
 81     tree[2][nu<<1]=(tree[2][nu<<1]+2*mark1[nu]*tree[1][nu<<1]+(mid-l+1)*mark1[nu]*mark1[nu])%mod;
 82     tree[1][nu<<1]=(tree[1][nu<<1]+mark1[nu]*(mid-l+1))%mod;
 83     mark2[nu<<1]=(mark2[nu<<1]*mark2[nu])%mod;
 84     mark1[nu<<1]=(mark1[nu<<1]*mark2[nu]+mark1[nu])%mod;
 85     tree[3][nu<<1|1]=(tree[3][nu<<1|1]*mark2[nu]*mark2[nu]*mark2[nu])%mod;
 86     tree[2][nu<<1|1]=(tree[2][nu<<1|1]*mark2[nu]*mark2[nu])%mod;
 87     tree[1][nu<<1|1]=(tree[1][nu<<1|1]*mark2[nu])%mod;
 88     tree[3][nu<<1|1]=(tree[3][nu<<1|1]+3*tree[2][nu<<1|1]*mark1[nu]+3*tree[1][nu<<1|1]*mark1[nu]*mark1[nu]+(r-mid)*mark1[nu]*mark1[nu]*mark1[nu])%mod;
 89     tree[2][nu<<1|1]=(tree[2][nu<<1|1]+2*mark1[nu]*tree[1][nu<<1|1]+(r-mid)*mark1[nu]*mark1[nu])%mod;
 90     tree[1][nu<<1|1]=(tree[1][nu<<1|1]+mark1[nu]*(r-mid))%mod;
 91     mark2[nu<<1|1]=(mark2[nu<<1|1]*mark2[nu])%mod;
 92     mark1[nu<<1|1]=(mark1[nu<<1|1]*mark2[nu]+mark1[nu])%mod;
 93     mark1[nu]=mark3[nu]=0;mark2[nu]=1;
 94 }
 95 
 96 void change(int l,int r,int nu)
 97 {
 98     if(L<=l&&r<=R)
 99     {
100         if(b==3)
101         {
102             mark1[nu]=a;
103             mark2[nu]=1;
104             mark3[nu]=1;
105             tree[1][nu]=a*(r-l+1)%mod;
106             tree[2][nu]=(a*a*(r-l+1))%mod;
107             tree[3][nu]=(a*a*a*(r-l+1))%mod;
108         }
109         if(b==2)
110         {
111             mark1[nu]=(mark1[nu]*a)%mod;
112             mark2[nu]=(mark2[nu]*a)%mod;
113             tree[1][nu]=(tree[1][nu]*a)%mod;
114             tree[2][nu]=(tree[2][nu]*a*a)%mod;
115             tree[3][nu]=(tree[3][nu]*a*a*a)%mod;
116         }
117         if(b==1)
118         {
119             mark1[nu]=(mark1[nu]+a)%mod;
120             tree[3][nu]=(tree[3][nu]+3*tree[2][nu]*a+3*tree[1][nu]*a*a+(r-l+1)*a*a*a)%mod;
121             tree[2][nu]=(tree[2][nu]+2*a*tree[1][nu]+(r-l+1)*a*a)%mod;
122             tree[1][nu]=(tree[1][nu]+a*(r-l+1))%mod;
123         }
124         return;
125     }
126     down(l,r,nu);
127     int mid=(l+r)>>1;
128     if(L<=mid)
129         change(l,mid,nu<<1);
130     if(R>=mid+1)
131         change(mid+1,r,nu<<1|1);
132     up(nu);
133 }
134 
135 long long sum(int l,int r,int nu)
136 {
137     long long su=0;
138     if(L<=l&&r<=R)
139         return tree[a][nu];
140     down(l,r,nu);
141     int mid=(l+r)>>1;
142     if(L<=mid)
143         su+=sum(l,mid,nu<<1);
144     if(R>=mid+1)
145         su+=sum(mid+1,r,nu<<1|1);
146     su=su%mod;
147     return su;
148 }
祝AC哟;
Just close your eyes, you`ll be alright, no one can hurt you after you die.
原文地址:https://www.cnblogs.com/nietzsche-oier/p/6235586.html