HDU 1698 Just a Hook 线段树成段更新
来源:互联网 发布:单片机与plc的区别 编辑:程序博客网 时间:2024/06/05 06:43
算是我真正意义上的区间更新的第一题,我是这样理解区间更新的:
为了节省时间,在更新区间的时候不必每次都更新到叶子节点。如果当前节点的的区间被包含在查询区间内,就暂时只更新这个节点。但是如果仅仅这样,将来在下次更新的时候,如果涉及了该节点的孩子节点,就会出错。
所以有一个办法:在更新的时候,如果我们明确知道了该节点的儿子节点涉及到了将要更新的区间,就事先把它的左右儿子节点按照父节点的val更新了,由于更新是递归实现的,所以如果它的孙子节点也涉及了,孙子节点会在儿子节点的递归层被更新。
这样做肯定比每次都更新到叶子节点大大节省了时间。
AC代码:
/* ***********************************************Author :angon************************************************ */#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <stack>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;#define REP(i,k,n) for(int i=k;i<n;i++)#define REPP(i,k,n) for(int i=k;i<=n;i++)#define scan(d) scanf("%d",&d)#define scann(n,m) scanf("%d%d",&n,&m)#define mst(a,k) memset(a,k,sizeof(a));#define LL long long#define maxn 100005#define mod 100000007/*inline int read(){ int s=0; char ch=getchar(); for(; ch<'0'||ch>'9'; ch=getchar()); for(; ch>='0'&&ch<='9'; ch=getchar())s=s*10+ch-'0'; return s;}inline void print(int x){ if(!x)return; print(x/10); putchar(x%10+'0');}*/int n;struct node{ int l,r,v,sum; //v 代表类型,sum代表总和}seg[maxn*4];void build(int i,int l,int r){ seg[i].l=l; seg[i].r=r; seg[i].v=1; if(l==r) { seg[i].sum=1; return ; } int mid=(l+r)>>1; build(i<<1,l,mid); build(i<<1|1,mid+1,r); seg[i].sum=seg[i<<1].sum+seg[i<<1|1].sum;}void update(int i,int l,int r,int val){ if(seg[i].v==val) return ; //剪枝 if(l<=seg[i].l && r>=seg[i].r) { seg[i].v=val; seg[i].sum=(seg[i].r-seg[i].l+1)*val; return ; } if(seg[i].v>0) //如果大于0,说明区间里面颜色一样 { //由上面一个if没有return可知后面必定对子树进行操作, seg[i<<1].v=seg[i<<1|1].v=seg[i].v; //所以先更新孩子节点 seg[i<<1].sum=(seg[i<<1].r-seg[i<<1].l+1)*seg[i].v; seg[i<<1|1].sum=(seg[i<<1|1].r-seg[i<<1|1].l+1)*seg[i].v; seg[i].v=0; } int mid=(seg[i].l+seg[i].r)>>1; if(l<=mid) update(i<<1,l,r,val); if(r>mid) update(i<<1|1,l,r,val); seg[i].sum=seg[i<<1].sum+seg[i<<1|1].sum;}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int t,q,x,y,c; scan(t); int cas=1; while(t--) { scan(n); build(1,1,n); scan(q); while(q--) { scanf("%d%d%d",&x,&y,&c); update(1,x,y,c); } printf("Case %d: The total value of the hook is %d.\n",cas++,seg[1].sum); } return 0;}
附kuangbin大神的代码,更加符合标准,更模版化,再看一遍也许可以帮助理解
/*HDU 1689线段树成段更新*/#include<stdio.h>#include<string.h>#include<algorithm>#include<iostream>using namespace std;const int MAXN=100010;struct Node{ int l,r; int lazy,tag; int sum;}segTree[MAXN*3];void Build(int i,int l,int r){ segTree[i].l=l; segTree[i].r=r; segTree[i].lazy=0; segTree[i].tag=0; if(l==r) { segTree[i].sum=1; return; } int mid=(l+r)>>1; Build(i<<1,l,mid); Build((i<<1)|1,mid+1,r); segTree[i].sum=segTree[i<<1].sum+segTree[(i<<1)|1].sum;}void update(int i,int l,int r,int v){ if(segTree[i].l==l&&segTree[i].r==r)//成段更新 { segTree[i].lazy=1; segTree[i].tag=v; segTree[i].sum=(r-l+1)*v; return; } int mid=(segTree[i].l+segTree[i].r)>>1; if(segTree[i].lazy==1) { segTree[i].lazy=0; update(i<<1,segTree[i].l,mid,segTree[i].tag); update((i<<1)|1,mid+1,segTree[i].r,segTree[i].tag); segTree[i].tag=0; } if(r<=mid) update(i<<1,l,r,v); else if(l>mid)update((i<<1)|1,l,r,v); else { update(i<<1,l,mid,v); update((i<<1)|1,mid+1,r,v); } segTree[i].sum=segTree[i<<1].sum+segTree[(i<<1)|1].sum;}int main(){ // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int x,y,z; int n; int m; int T; scanf("%d",&T); int iCase=0; while(T--) { iCase++; scanf("%d%d",&n,&m); Build(1,1,n); while(m--) { scanf("%d%d%d",&x,&y,&z); update(1,x,y,z); } printf("Case %d: The total value of the hook is %d.\n",iCase,segTree[1].sum); } return 0;}
0 0
- HDU 1698 线段树成段更新 Just a Hook
- hdu 1698 Just a Hook 线段树成段更新
- HDU 1698 Just a Hook / 线段树成段更新
- HDU-1698 Just a Hook 线段树成段更新
- HDU 1698 Just a Hook,线段树成段更新
- hdu 1698 Just a Hook 线段树成段更新
- HDU 1698 Just a Hook(线段树成段更新求和)
- HDU 1698 Just a Hook(线段树成段更新)
- HDU 1698 Just a Hook(线段树成段更新)
- HDU 1698 Just a Hook(线段树成段更新)
- 线段树成段更新 hdu 1698 Just a Hook
- hdu 1698 Just a Hook(线段树成段更新lazy)
- HDU 1698 Just a Hook 线段树成段更新
- HDU-1698Just a Hook-线段树成段更新
- hdu Just a Hook 线段树成段更新.cpp
- HDU 1698 Just a Hook [线段树-成段更新]
- HDU 1698 Just a Hook 线段树区间更新
- hdu 1698 Just a Hook(线段树 成段更新)
- exFAT 文件系统格式
- 在这个比长的时代,偏偏有人胜在了短小精悍
- 纪念自己菜鸟生涯的一个开始---闰年计算器
- 58、微信-我-我的二维码MyCodeActivity
- jquery tmpl 详解
- HDU 1698 Just a Hook 线段树成段更新
- 【C#】日期时间处理总结
- iOS如何快速解决PCH文件的路径找不到问题
- 页面自动刷新
- 59、微信-我-设置SettingActivity
- php 创建类
- Qt Model/View( 一)
- 60、微信-聊天页面ChatActivity
- 中国残疾人网页