HDU 4578——Transformation
2017-08-18 10:03
127 查看
TransformationTime Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)Total Submission(s): 5927 Accepted Submission(s): 1472 [align=left]Problem Description[/align] 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+…+ayp. Yuanfang has no idea of how to do it. So he wants to ask you to help him. [align=left]Input[/align] There are no more than 10 test cases. For each case, the first line contains two numbers n and m, meaning that there are n integers and m operations. 1 <= n, m <= 100,000. Each the following m lines contains an operation. Operation 1 to 3 is in this format: "1 x y c" or "2 x y c" or "3 x y c". Operation 4 is in this format: "4 x y p". (1 <= x <= y <= n, 1 <= c <= 10,000, 1 <= p <= 3) The input ends with 0 0. [align=left]Output[/align] For each operation 4, output a single integer in one line representing the result. The answer may be quite large. You just need to calculate the remainder of the answer when divided by 10007. [align=left]Sample Input[/align] 5 5 3 3 5 7 1 2 4 4 4 1 5 2 2 2 5 8 4 3 5 3 0 0 [align=left]Sample Output[/align] 307 7489 [align=left]Source[/align] 2013ACM-ICPC杭州赛区全国邀请赛 题意: n个数初始为0,m个操作 操作分4种: 1 x y c x到y的所有数加c 2 x y c x到y的所有数乘c 3 x y c x到y的所有数变成c 4 x y p 求x到y的所有数的p次方的和 (1<=p<=3) 分析: 我们假设x到y的和为a,,x到y的平方的和为b,x到y的次方的和为d那么: 操作1过后 d=d+3*c*b+3*c*c*a+c*c*c*(y-x+1) 通过两个数的次方和推导:(x1+c)^3+(x2+c)^3=x1^3+x2^3+3*c*(x1^2+x2^2)+3*c*c*(x1+x2)+c^3*2 b=b+2*c*a+c*c*(y-x+1) 通过两个数的平方和推导 (x1+c)^2+(x2+c)^2=x1^2+x2^2+2*c*(x1+x2)+c^2*2 a=a+c*(y-x+1) ps:因为d的推导要用到a,b b的推导要用到a所以每一次需要先算次方,再算平方,最后算普通和 操作2过后 a=a*c b=b*c*c d=d*c*c*c 操作3过后 a=c*(y-x+1) b=c*c*(y-x+1) d=c*c*c*(y-x+1) 可以看到,普通和,平方和,次方和的变化都与变化之前的三种和有关系,所以只存普通和会给求平方和与次方和造成不方便,所以我们把3个值一起存,一起更新。 #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<vector> #include<cmath> #define INF 0x3f3f3f3f #define EXP 0.00000001 #define MOD 10007 #define MAXN 100005 #define ltree 2*id,ll,mid #define rtree 2*id+1,mid+1,rr #define FO(i,n,m) for(int i=n;i<=m;++i) #define mem(a) memset(a,0,sizeof(a)) typedef long long LL; using namespace std; int n,m; int add[4*MAXN]; int mul[4*MAXN]; int ch[4*MAXN]; int tree1[4*MAXN],tree2[4*MAXN],tree3[4*MAXN]; void Pushup(int id) { tree1[id]=(tree1[2*id]+tree1[2*id+1])%MOD; tree2[id]=(tree2[2*id]+tree2[2*id+1])%MOD; tree3[id]=(tree3[2*id]+tree3[2*id+1])%MOD; } void Pushdown(int id,int ll,int rr) { int llen=(ll+rr)/2-ll+1; int rlen=rr-(ll+rr)/2; int lt=2*id,rt=2*id+1; if(ch[id]) { ch[lt]=ch[rt]=ch[id]; add[lt]=add[rt]=0; mul[lt]=mul[rt]=1; tree1[lt]=ch[id]*llen%MOD; tree2[lt]=ch[id]*ch[id]%MOD*llen%MOD; tree3[lt]=ch[id]*ch[id]%MOD*ch[id]%MOD*llen%MOD; tree1[rt]=ch[id]*rlen%MOD; tree2[rt]=ch[id]*ch[id]%MOD*rlen%MOD; tree3[rt]=ch[id]*ch[id]%MOD*ch[id]%MOD*rlen%MOD; ch[id]=0; } if(mul[id]!=1) { mul[lt]=mul[lt]*mul[id]%MOD; mul[rt]=mul[rt]*mul[id]%MOD; add[lt]=add[lt]*mul[id]%MOD; add[rt]=add[rt]*mul[id]%MOD; tree1[lt]=tree1[lt]*mul[id]%MOD; tree2[lt]=tree2[lt]*mul[id]%MOD*mul[id]%MOD; tree3[lt]=tree3[lt]*mul[id]%MOD*mul[id]%MOD*mul[id]%MOD; tree1[rt]=tree1[rt]*mul[id]%MOD; tree2[rt]=tree2[rt]*mul[id]%MOD*mul[id]%MOD; tree3[rt]=tree3[rt]*mul[id]%MOD*mul[id]%MOD*mul[id]%MOD; mul[id]=1; } if(add[id]) { add[lt]=(add[lt]+add[id])%MOD; add[rt]=(add[rt]+add[id])%MOD; tree3[lt]=(tree3[lt]+3*add[id]*tree2[lt]%MOD+3*add[id]*add[id]%MOD*tree1[lt]%MOD+add[id]*add[id]%MOD*add[id]%MOD*llen%MOD)%MOD; tree2[lt]=(tree2[lt]+2*add[id]*tree1[lt]%MOD+add[id]*add[id]%MOD*llen%MOD)%MOD; tree1[lt]=(tree1[lt]+add[id]*llen%MOD)%MOD; tree3[rt]=(tree3[rt]+3*add[id]*tree2[rt]%MOD+3*add[id]*add[id]%MOD*tree1[rt]%MOD+add[id]*add[id]%MOD*add[id]%MOD*rlen%MOD)%MOD; tree2[rt]=(tree2[rt]+2*add[id]*tree1[rt]%MOD+add[id]*add[id]%MOD*rlen%MOD)%MOD; tree1[rt]=(tree1[rt]+add[id]*rlen%MOD)%MOD; add[id]=0; } } void Build(int id,int ll,int rr) { add[id]=0; mul[id]=1; ch[id]=0; if(ll==rr) { tree1[id]=0; tree2[id]=0; tree3[id]=0; return; } int mid=(ll+rr)/2; Build(ltree); Build(rtree); Pushup(id); } void Update(int id,int ll,int rr,int x,int y,int op,int c) { if(x<=ll&&rr<=y) { if(op==1) { add[id]=(add[id]+c)%MOD; tree3[id]=(tree3[id]+3*c*tree2[id]%MOD+3*c*c%MOD*tree1[id]%MOD+c*c%MOD*c%MOD*(rr-ll+1)%MOD)%MOD; tree2[id]=(tree2[id]+2*c*tree1[id]%MOD+c*c%MOD*(rr-ll+1)%MOD)%MOD; tree1[id]=(tree1[id]+c*(rr-ll+1)%MOD)%MOD; return; } if(op==2) { mul[id]=mul[id]*c%MOD; add[id]=add[id]*c%MOD; tree1[id]=tree1[id]*c%MOD; tree2[id]=tree2[id]*c%MOD*c%MOD; tree3[id]=tree3[id]*c%MOD*c%MOD*c%MOD; return; } if(op==3) { add[id]=0; mul[id]=1; ch[id]=c; tree1[id]=c*(rr-ll+1)%MOD; tree2[id]=c*c%MOD*(rr-ll+1)%MOD; tree3[id]=c*c%MOD*c%MOD*(rr-ll+1)%MOD; return; } } Pushdown(id,ll,rr); int mid=(ll+rr)/2; if(y<=mid) Update(ltree,x,y,op,c); else if(x>mid) Update(rtree,x,y,op,c); else { Update(ltree,x,mid,op,c); Update(rtree,mid+1,y,op,c); } Pushup(id); } int Query(int id,int ll,int rr,int x,int y,int pow) { if(x<=ll&&rr<=y) { if(pow==1) return tree1[id]; if(pow==2) return tree2[id]; if(pow==3) return tree3[id]; } Pushdown(id,ll,rr); int mid=(ll+rr)/2; if(y<=mid) return Query(ltree,x,y,pow); else if(x>mid) return Query(rtree,x,y,pow); else return (Query(ltree,x,mid,pow)+Query(rtree,mid+1,y,pow))%MOD; } int main() { while(~scanf("%d%d",&n,&m)) { if(n==0&&m==0) break; Build(1,1,n); while(m--) { int op,x,y,c; scanf("%d%d%d a2e0 %d",&op,&x,&y,&c); if(op==4) printf("%d\n",Query(1,1,n,x,y,c)); else Update(1,1,n,x,y,op,c); } } return 0; } |
相关文章推荐
- hdu 4578 Transformation(线段树+多种操作)
- HDU-4578:Transformation(有条件的延迟标记)
- HDU 4578 Transformation(13年杭州邀请赛-C题-线段树)
- hdu 4578 Transformation (线段树)
- hdu 4578 Transformation(线段树+多种操作)
- HDU 4578 Transformation (线段树)
- HDU 4578 Transformation (线段树)
- hdu 4578 Transformation(线段树+多种操作)
- HDU 4578-Transformation(线段树)
- hdu 4578 Transformation(线段树区间操作)
- hdu 4578 Transformation(区间线段树)
- hdu 4578 Transformation(线段树)
- HDU 4578 Transformation
- hdu 4578 Transformation(线段树+多种操作)
- hdu 4578 Transformation
- hdu 4578 Transformation
- HDU 4578 Transformation 解题报告(线段树,2013杭州邀请赛)
- hdu 4578 Transformation(线段树)
- HDU 4578 Transformation[线段树]
- hdu 4578 Transformation(线段树+多种操作)