HDOJ 4578 线段树
来源:互联网 发布:拼接屏调试软件 编辑:程序博客网 时间:2024/05/01 02:20
关键问题是要同时维护每个节点的三个值,sum【1】一次方,sum【2】二次方,sum【3】三次方,还有个update()维护每次的sum值的改变。
然后有个lazy【】标记,既然有lazy标记,就要有pushdown的维护。三种操作,+c,*c,=c,显然=c优先级最高,然后是*c,最后是+c,维护每个节点扣留的操作,需要按照这种顺序。
可是写出来wa了4遍。
对线段树的理解还是不够透彻。
留个链接吧,http://blog.csdn.net/kk303/article/details/9900919,以后再看。
有误的代码。。。
#include <iostream>#include <fstream>#include <cstring>using namespace std;#define N 100005#define T 10007int sum[N*4][4],ord[N*4][4];bool lazy[N*4];int n,m;void update(int op,int len,int c,int now){ len=len%T; if (op==3){ sum[now][1]=len*c%T; sum[now][2]=sum[now][1]*c%T; sum[now][3]=sum[now][2]*c%T; } else if (op==2){ sum[now][1]=sum[now][1]*c%T; sum[now][2]=sum[now][2]*c%T*c%T; sum[now][3]=(sum[now][3]*((c*c)%T))%T*c%T; } else { sum[now][3]=sum[now][3]+3*sum[now][2]*c%T+3*(sum[now][1]*c)%T*c%T+(c*c)%T*(c*len)%T%T; sum[now][2]=sum[now][2]+2*sum[now][1]*c%T+(c*c)%T*len%T; sum[now][1]=sum[now][1]+c*len%T; }}void PushDown(int len,int now){ if (!lazy[now]) return; lazy[now]=false; lazy[now<<1]= lazy[now<<1|1] =true; if (ord[now][3]){ update(3,len-(len>>1),ord[now][3],now<<1); update(3,len>>1,ord[now][3],now<<1|1); for (int i=1;i<4;i++) ord[now<<1][i] = ord[now<<1|1][i] = ord[now][i]; } else { ord[now<<1][2]=ord[now<<1][2]*ord[now][2]%T; ord[now<<1][1]=(ord[now<<1][1]*ord[now][2]%T+ord[now][1])%T; ord[now<<1|1][2]=ord[now<<1|1][2]*ord[now][2]%T; ord[now<<1|1][1]=(ord[now<<1|1][1]*ord[now][2]%T+ord[now][1])%T; } update(2,len-(len>>1),ord[now][2],now<<1); update(1,len-(len>>1),ord[now][1],now<<1); update(2,len>>1,ord[now][2],now<<1|1); update(1,len>>1,ord[now][1],now<<1|1); ord[now][3] = ord[now][1] = 0; ord[now][2] = 1; return ;}void Insert(int op,int L,int R,int c,int l,int r,int now){ if (L<=l && r<=R){ update(op,r-l+1,c,now); lazy[now]=true; if (op==3){ ord[now][3]=c,ord[now][2]=1,ord[now][1]=0; } else if (op==2){ ord[now][1]=ord[now][1]*c%T; ord[now][2]=ord[now][2]*c%T; } else { ord[now][1]=(ord[now][1]+c)%T; } return ; } PushDown(r-l+1,now); int mid=(r+l)>>1; if (L<=mid) Insert(op,L,R,c,l,mid,now<<1); if (R>mid) Insert(op,L,R,c,mid+1,r,now<<1|1); for (int i=1;i<4;i++) sum[now][i]=(sum[now<<1][i]+sum[now<<1|1][i])%T; return ;}int Search(int L,int R,int c,int l,int r,int now){ if (L<=l && R>=r){ return sum[now][c]; } PushDown(r-l+1,now); int mid=(l+r)>>1; int ans=0; if (L<=mid) ans+=Search(L,R,c,l,mid,now<<1); if (mid<R) ans+=Search(L,R,c,mid+1,r,now<<1|1); return ans%T;}int main(){ freopen("1.in","r",stdin); //freopen("1.out","w",stdout); scanf("%d%d",&n,&m); while (!(n==0 && m==0)){ memset(sum,0,sizeof(sum)); memset(ord,0,sizeof(ord)); for (int i=1;i<=4*N;i++) ord[i][2]=1; memset(lazy,false,sizeof(lazy)); for (int i=0;i<m;i++){ int op,l,r,c; scanf("%d%d%d%d",&op,&l,&r,&c); c=c%T; if (op<=3) Insert(op,l,r,c,1,n,1); else printf("%d\n",Search(l,r,c,1,n,1)); } scanf("%d%d",&n,&m); } return 0;}
- hdoj 4578 线段树
- HDOJ 4578 线段树
- 【线段树】 HDOJ 4578 Transformation
- HDOJ 1166(线段树)
- HDOJ 1754 (线段树)
- HDOJ 1698 (线段树)
- hdoj 1698 线段树
- hdoj 1754 【线段树】
- hdoj 4267 - 线段树
- hdoj 1166 线段树
- hdoj 4027 线段树
- HDOJ 1166 -----线段树
- HDOJ 1754 ------线段树
- HDOJ 1698-----线段树
- hdoj 4747 线段树
- hdoj 5289 线段树
- HDU/HDOJ 1166 线段树
- hdoj - 2795 -Billboard(线段树)
- struct和class的异同
- org.xml.sax.SAXException
- php验证码实现及使用--面向过程版
- uva 123 - Searching Quickly
- [ JS ] 某一个月份的若干个月份之后的月份
- HDOJ 4578 线段树
- latex 生成 中文pdf文档
- string类型转换成double-long
- jQuery Custom PopUp Window
- Linux下的tar压缩解压缩命令详解
- jQuery Custom PopUp Window
- HDU 3555 Bomb
- java中的注解
- CSS块级元素、内联元素概念