hdu 1698
题意: 给你a,b,c,在a,b区间内覆盖c,求最终的和........
这一题我也是醉了........
想了好久,一直不知道怎么更新成段更新区间.....后来看了标程,才做出来的.......
代码敲完,提交RE.....然后我就看啊看.....在移位的地方加了括号(真是作死,,,,,,)
期间我一直在纠结用+替换|会不会超时........
后来提交又TLE,,,,,,,,,,nimei....不是说加了ios可以的吗.....
.....
反正后来A了,是很无语的A掉,,,,,,,题目做的我蛋疼........
AC代码:
#include <iostream> #include <stdio.h> //#define Max 100010; using namespace std; const int Max = 100010; struct S { int l,r,lazy,flag,sum; }; S segtree[Max*3]; void build(int i,int l,int r)//初始化线段树 { segtree[i].l=l;//初始化变量.... segtree[i].r=r; segtree[i].lazy=0; segtree[i].flag=0; if(l==r) //到达叶子节点,递归结束(一开始我把结束条件放到前面....就会报错....后来想了下,自己好笨哦!!!!) { segtree[i].sum=1; //把每个节点都初始化sum=1 return; } int m=(l+r)>>1; build(i<<1,l,m); //递归左子树 build((i<<1)+1,m+1,r);//递归右子树 segtree[i].sum=segtree[i<<1].sum+segtree[(i<<1)+1].sum;//初始化节点sum和 } void update(int i,int l,int r,int v)//更新节点(区间更新) { int m=(segtree[i].r+segtree[i].l)>>1; if(segtree[i].l==l&&segtree[i].r==r) //这里是延迟标记的判断处,对每次读入的数据都会进行一次调用, { //作用是后面数据不用处理到叶子节点.......(就是线段树的优势吧....) segtree[i].lazy=1; //标记 segtree[i].flag=v; segtree[i].sum=(r-l+1)*v;//记下此段区间的和 return; } if(segtree[i].lazy==1) //因为第一组数据不会调用,所以只是方便后面处理 { segtree[i].lazy=0; //调用完后,初始化重新标记 update(i<<1,segtree[i].l,m,segtree[i].flag); //所以这里要从segtree[i]开始递归 update((i<<1)+1,m+1,segtree[i].r,segtree[i].flag); segtree[i].flag=0; } if(m>=r) //在没有进入lazy下,只需要判断m在(l,r)区间的情况.....然后进行递归更新 update(i<<1,l,r,v); else if(m<l) update((i<<1)+1,l,r,v); else { update(i<<1,l,m,v); update((i<<1)+1,m+1,r,v); } segtree[i].sum=segtree[i<<1].sum+segtree[(i<<1)+1].sum;//同理,仍需要处理sum和问题 } int main() { //ios::sync_with_stdio; int t; int n,m,a,b,c,k=0; //cin>>t; scanf("%d",&t); while(t--) { //cout<<1; //cin>>n>>m; scanf("%d%d",&n,&m); build(1,1,n);//从第一个节点开始,节点为1-n //cout<<1; while(m--) { //cin>>a>>b>>c; scanf("%d%d%d",&a,&b,&c); update(1,a,b,c); //cout<<1; } //cout<<1; //cout<<"Case "<<++k<<": The total value of the hook is "<<segtree[1].sum<<endl; printf("Case %d: The total value of the hook is %d.\n",++k,segtree[1].sum); } return 0; }