HDOJ 4578/2013年杭州邀请赛C题 - Transformation 线段树...比较蛋疼的维护PushDown
来源:互联网 发布:js后退事件 编辑:程序博客网 时间:2024/06/10 22:40
题意:
很裸.......
题解:
因为要统计3个次方...构造三颗线段树(同时更新查询)sum[1][MAXN]为一次方...sum[2][MAXN]为二次方..sum[3][MAXN]为三次方..
首先看如何更新...令[l,r]长度为len最容易的是区间[l,r]复制相为c...sum[1][now]=len*c
sum[2][now]=len*c*c
sum[3][now]=len*c*c*c
区间[l,r]乘c也容易: sum[1][now]=sum[1][now]*c
sum[2][now]=sum[2][now]*c*c
sum[3][now]=sum[3][now]*c*c*c
区间求和.. 先sum[3][now]...因为(a+c)^3=a^3+3a^a*c+3*a*c^2+c^3.则sum[3][now]=sum[3][now]+3*sum[2][now]*c+3*c*c*sum[1][now]+c*c*c*len
再sum[2]][now] 因为(a+c)^2=a^2+2ac+c^2..则sum[2][now]=sum[2][now]+2*sum[1][now]*c+c*c *len
最后 sum[1][now]..直接sum[1][now]=sum[1][now]+len*c
这些都比较简单....关键是维护懒惰标记...有三个操作..对于每个点就有三个懒惰标记来维护...但是操作间是有顺序的..比如先做了+/*运算..后面来个赋值运算..前面的运算就不做效了..又现做乘法再做加法和先做加法再做乘法..结果是完全不同的...我的解决办法是定了一个运算顺序..推进懒惰标记时..先处理赋值运算..再处理乘法运算..最后处理加法运算..在更新懒惰标记时..也保持这种顺序运算的正确性..
Program:
#include<iostream>#include<stdio.h>#include<cmath>#include<queue>#include<stack>#include<string.h>#include<map>#include<set>#include<algorithm>#define oo 10007#define MAXN 100005#define ll intusing namespace std;ll sum[4][MAXN<<2],col[4][MAXN<<2]; // 1+ 2* 3=bool need[MAXN<<2];void up(int tp,int len,ll c,int now){ if (tp==1) { sum[3][now]=(sum[3][now]+3*sum[2][now]%oo*c%oo+3*sum[1][now]%oo*c%oo*c%oo+c*c%oo*c%oo*len%oo)%oo; sum[2][now]=(sum[2][now]+2*c%oo*sum[1][now]%oo+c*c%oo*len%oo)%oo; sum[1][now]=(sum[1][now]+c*len)%oo; }else if (tp==2) { sum[1][now]=sum[1][now]*c%oo; sum[2][now]=c*c%oo*sum[2][now]%oo; sum[3][now]=c*c%oo*c%oo*sum[3][now]%oo; }else if (tp==3) { sum[1][now]=c*len%oo; sum[2][now]=c*c%oo*len%oo; sum[3][now]=c*c%oo*c%oo*len%oo; }}void PushDown(int len,int now) // 先覆盖..再乘..再加 { if (!need[now]) return; need[now]=false,need[now<<1]=need[now<<1|1]=true; if (col[3][now]) { up(3,len-(len>>1),col[3][now],now<<1); up(3,len>>1,col[3][now],now<<1|1); col[3][now<<1]=col[3][now<<1|1]=col[3][now]; col[1][now<<1]=col[1][now<<1|1]=col[1][now]; col[2][now<<1]=col[2][now<<1|1]=col[2][now]; }else { col[2][now<<1]=(col[2][now<<1]*col[2][now])%oo; col[2][now<<1|1]=col[2][now<<1|1]*col[2][now]%oo; col[1][now<<1]=(col[1][now<<1]*col[2][now]+col[1][now])%oo, col[1][now<<1|1]=(col[1][now<<1|1]*col[2][now]+col[1][now])%oo; } up(2,len-(len>>1),col[2][now],now<<1),up(2,len>>1,col[2][now],now<<1|1); up(1,len-(len>>1),col[1][now],now<<1),up(1,len>>1,col[1][now],now<<1|1); col[3][now]=col[1][now]=0,col[2][now]=1; return;}void update(int L,int R,ll c,int tp,int l,int r,int now){ if (L<=l && R>=r) { up(tp,r-l+1,c,now); need[now]=true; if (tp==3) col[1][now]=0,col[2][now]=1,col[3][now]=c; else if (tp==2) { col[1][now]=col[1][now]*c%oo, col[2][now]=col[2][now]*c%oo; }else if (tp==1) col[1][now]=(col[1][now]+c)%oo; return; } PushDown(r-l+1,now); int mid=(l+r)>>1; if (L<=mid) update(L,R,c,tp,l,mid,now<<1); if (R>mid) update(L,R,c,tp,mid+1,r,now<<1|1); sum[1][now]=(sum[1][now<<1]+sum[1][now<<1|1])%oo; sum[2][now]=(sum[2][now<<1]+sum[2][now<<1|1])%oo; sum[3][now]=(sum[3][now<<1]+sum[3][now<<1|1])%oo; return;}ll query(int L,int R,int tp,int l,int r,int now){ if (L<=l && R>=r) return sum[tp][now]; PushDown(r-l+1,now); int mid=(l+r)>>1; ll ans=0; if (L<=mid) ans+=query(L,R,tp,l,mid,now<<1); if (R>mid) ans+=query(L,R,tp,mid+1,r,now<<1|1); return ans%oo; }int main(){ int n,m; while (~scanf("%d%d",&n,&m) && (n || m)) { memset(sum,0,sizeof(sum)); memset(col,0,sizeof(col)); for (int i=0;i<(MAXN<<2);i++) col[2][i]=1; memset(need,false,sizeof(need)); int tp,l,r,p; while (m--) { scanf("%d%d%d%d",&tp,&l,&r,&p); if (tp<4) update(l,r,p,tp,1,n,1); else printf("%d\n",query(l,r,p,1,n,1)); } } return 0;}/*13 41 1 4 69884 1 3 12 1 13 6404 1 3 115 31 1 12 10 3 1 15 24 1 4 178 41 1 44 78152 1 20 5423 1 47 14 1 36 10 0*/
- HDOJ 4578/2013年杭州邀请赛C题 - Transformation 线段树...比较蛋疼的维护PushDown
- HDU 4578 Transformation(13年杭州邀请赛-C题-线段树)
- HDU 4578 Transformation 解题报告(线段树,2013杭州邀请赛)
- HDUOJ 4578 2013杭州邀请赛重现 Transformation
- HDOJ 4578 && 2013杭州邀请赛
- hdu 4578 Transformation2013杭州邀请赛C(简单线段树)
- HDU 4578 Transformation(2013 杭州赛区全国邀请赛 1003)
- hdu 4578 Transformation 2013ACM-ICPC杭州赛区全国邀请赛
- HDOJ 4576/2013年杭州邀请赛A题 Robot 暴力~
- 【线段树】 HDOJ 4578 Transformation
- HDOJ 4585 && 2013杭州邀请赛
- HDOJ 4584/2013年杭州邀请赛I题 Building bridges 水题
- HDOJ 4585/2013年杭州邀请赛J题 - Shaolin Treap水~
- hdu 4578 Transformation(线段树维护区间次方和)
- 4578 Transformation 线段树
- HDU4577(2013年ACM杭州赛区邀请赛B题)
- 杭州邀请赛的总结
- HDU 4578 Transformation --线段树,好题
- 【xinfanqie】简单三个小步骤快速设置个性化Win8
- 高手解析:PDF格式与EXCEL格式转换的办法【绿色】
- libgdx,android游戏框架
- [SOA] Mule ESB 3.x 入门(一)—— 消息流
- schema对象介绍
- HDOJ 4578/2013年杭州邀请赛C题 - Transformation 线段树...比较蛋疼的维护PushDown
- 导致物理内存使用率高的原因以及解决办法【xiame】
- grub快速修复
- HDU1214--圆桌会议 HDU(90)
- android,获取北京时区时间
- hdu(2831)Plants VS Zombies
- UFOs
- 机器学习基础-概率论知识点
- Windows 开发之注册表操作-UAC