Description
  在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了。
不过,她经常回忆起以前在乡间漫步的情景。昔日,乡下有依次编号为1…n的n个小村庄,某些村庄之间有一些双
向的土路。从每个村庄都恰好有一条路径到达村庄1(即比特堡)。并且,对于每个村庄,它到比特堡的路径恰好
只经过编号比它的编号小的村庄。另外,对于所有道路而言,它们都不在除村庄以外的其他地点相遇。在这个未开
化的地方,从来没有过高架桥和地下铁道。随着时间的推移,越来越多的土路被改造成了公路。至今,Blue Mary
还清晰地记得最后一条土路被改造为公路的情景。现在,这里已经没有土路了——所有的路都成为了公路,而昔日
的村庄已经变成了一个大都市。 Blue Mary想起了在改造期间她送信的经历。她从比特堡出发,需要去某个村庄,
并且在两次送信经历的间隔期间,有某些土路被改造成了公路.现在Blue Mary需要你的帮助:计算出每次送信她需
要走过的土路数目。(对于公路,她可以骑摩托车;而对于土路,她就只好推车了。)

Input
  第一行是一个数n(1 < = n < = 2 50000).以下n-1行,每行两个整数a,b(1 < = a以下一行包含一个整数m
(1 < = m < = 2 50000),表示Blue Mary曾经在改造期间送过m次信。以下n+m-1行,每行有两种格式的若干信息
,表示按时间先后发生过的n+m-1次事件:若这行为 A a b(a若这行为 W a, 则表示Blue Mary曾经从比特堡送信到
村庄a。

Output
  有m行,每行包含一个整数,表示对应的某次送信时经过的土路数目。

Sample Input
5

1 2

1 3

1 4

4 5

4

W 5

A 1 4

W 5

A 4 5

W 5

W 2

A 1 2

A 1 3

Sample Output
2

1

0

1
HINT

挺折磨人的一道题。。
首先得看懂题意,然后转换题意。两种操作:一种是求指定点的权值。另一种是更新一个区间。
将a-b的路径改为公路可以视为将a-b的路径的权值改为0,则题目转为经一系列边权的修改后询问根节点与一个节点的距离。刷一遍DFS序,比如样例中树的dfs序为1223345541。将进入的权值赋为1,离开的权值赋为-1,起点的进出权值都为0(进出权值记录在中间一行)。
得:
1 2 2 3 3 4 5 5 4 1
0 1 -1 1 -1 1 1 -1 -1 0
0 1 0 1 0 1 2 1 0 0
然后有什么用?我们可以发现起点到任意点N的距离都为N的进入点的前缀和(最下面一行)。
再试试修改,将1-4的权值改为0,只需将深度较深的点的进入权值改为0,离开的权值也改为0就好了。
1 2 2 3 3 4 5 5 4 1
0 1 -1 1 -1 0 1 -1 0 0
0 1 0 1 0 0 1 0 0 0
第二种操作直接修改深度大的点就好,这怎么也没想到。直接线段树或者树状数组修改就行。
①:线段树+dfs序

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
using namespace std;const int maxx=250500;
int head[maxx],pre[maxx],s[maxx],t[maxx];
int dep[maxx],fa[maxx];
struct edge{int next;int to;
}e[maxx*2];
struct node{int l;int r;int v;int lazy;
}p[maxx*4];
int n,m,tot,sign;
/*-----------------事前准备----------------*/
void init()
{tot=sign=0;memset(head,-1,sizeof(head));memset(dep,-1,sizeof(dep));
}
void add(int u,int v)
{e[tot].to=v,e[tot].next=head[u],head[u]=tot++;
}
/*--------------------dfs序-------------------*/
void dfs(int u,int f)
{dep[u]=dep[f]+1;s[u]=++sign;pre[sign]=u;fa[u]=f;for(int i=head[u];i!=-1;i=e[i].next){int to=e[i].to;if(to==f) continue;dfs(to,u);}t[u]=sign;
}
/*-------------------线段树-------------------*/
void pushup(int cur)
{p[cur].v=p[2*cur].v+p[2*cur+1].v;
}
void pushdown(int cur)
{if(p[cur].lazy){p[2*cur].lazy+=p[cur].lazy;p[2*cur+1].lazy+=p[cur].lazy;p[2*cur].v+=p[cur].lazy;p[2*cur+1].v+=p[cur].lazy;p[cur].lazy=0;}
}
void build(int l,int r,int cur)
{p[cur].l=l;p[cur].r=r;p[cur].v=p[cur].lazy=0;if(l==r){p[cur].v=dep[pre[l]];return ;}int mid=(l+r)/2;build(l,mid,2*cur);build(mid+1,r,2*cur+1);pushup(cur);
}
void update(int l,int r,int cur,int v)
{int L=p[cur].l;int R=p[cur].r;if(l<=L&&R<=r){p[cur].lazy+=v;p[cur].v+=v;return ;}pushdown(cur);int mid=(L+R)/2;if(r<=mid) update(l,r,2*cur,v);else if(l>mid) update(l,r,2*cur+1,v);else{update(l,mid,2*cur,v);update(mid+1,r,2*cur+1,v);}pushup(cur);
}
int query(int cur,int x)
{int L=p[cur].l;int R=p[cur].r;if(L==R){return p[cur].v;}pushdown(cur);int mid=(L+R)/2;if(x<=mid) return query(2*cur,x);else if(mid<x) return query(2*cur+1,x);
}
int main()
{init();scanf("%d",&n);int x,y;for(int i=1;i<n;i++){scanf("%d%d",&x,&y);add(x,y);add(y,x);}dfs(1,0);build(1,n,1);scanf("%d",&m);char xx[2];for(int i=1;i<=n+m-1;i++){scanf("%s",xx);if(xx[0]=='W'){scanf("%d",&x);printf("%d\n",query(1,s[x]));}else if(xx[0]=='A'){scanf("%d%d",&x,&y);x=max(x,y);update(s[x],t[x],1,-1);}}return 0;
}


②:树状数组+dfs序

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<vector>
#include<queue>
#define ll long long
using namespace std;const int maxx=250500;
int head[maxx],pre[maxx],dep[maxx],s[maxx],t[maxx];
int sum[maxx];
struct edge{int to;int next;
}e[maxx*4];
int n,m,tot,sign;
int lowbit(int x){return x&-x;}
void init()
{tot=sign=0;memset(head,-1,sizeof(head));memset(dep,-1,sizeof(dep));memset(pre,0,sizeof(pre));
}
void add(int u,int v)
{e[tot].to=v,e[tot].next=head[u],head[u]=tot++;
}
void dfs(int u,int f)
{dep[u]=dep[f]+1;s[u]=++sign;pre[sign]=u;for(int i=head[u];i!=-1;i=e[i].next){int to=e[i].to;if(to==f) continue;dfs(to,u);}t[u]=sign;
}
void update(int cur,int add)
{while(cur<=maxx*2){sum[cur]+=add;cur+=lowbit(cur);}
}
int query(int cur)
{int ans=0;while(cur>0){ans+=sum[cur];cur-=lowbit(cur);}return ans;
}
int main()
{init();scanf("%d",&n);int x,y;for(int i=1;i<n;i++){scanf("%d%d",&x,&y);add(x,y);add(y,x);}dfs(1,0);for(int i=2;i<=n;i++){update(s[i],1);update(t[i]+1,-1);}scanf("%d",&m);char xx[2];for(int i=1;i<=n+m-1;i++){scanf("%s",xx);if(xx[0]=='W'){scanf("%d",&x);printf("%d\n",query(s[x]));}else if(xx[0]=='A'){scanf("%d%d",&x,&y);update(max(s[x],s[y]),-1);update(min(t[x],t[y])+1,1);}}return 0;
}


线段树再一次被虐。。
明天就回学校打多校了,希望是一个积极的暑假,别虚度了!
努力加油a啊,(o)/~

1103: [POI2007]大都市meg(dfs序+线段树||树状数组)相关推荐

  1. BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]

    1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2221  Solved: 1179 [Submit][S ...

  2. BZOJ 1103: [POI2007]大都市meg

    Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了. 不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1.. ...

  3. BZOJ1103: [POI2007]大都市meg

    题解:dfs序用树状数组维护即可 Problem: 1103User: c20161007Language: C++Result: AcceptedTime:4872 msMemory:23832 k ...

  4. New Year Tree(dfs序+线段树+二进制)

    题意: 给出一棵 n个节点的树,根节点为 1.每个节点上有一种颜色 ci.m次操作.操作有两种: 1 u c:将以 u为根的子树上的所有节点的颜色改为c. 2 u:询问以 u为根的子树上的所有节点的颜 ...

  5. 求和(dfs序+线段树)

    题意: 已知有n个节点,有n−1条边,形成一个树的结构. 给定一个根节点k,每个节点都有一个权值,节点i的权值为vi​. 给m个操作,操作有两种类型: 1 a x :表示将节点a的权值加上x 2 a ...

  6. 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树

    题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...

  7. codeforces E. Jamie and Tree LCA+dfs序+线段树

    题解: 写起来还稍微有点麻烦. dfs序+线段树可以维护子树的整体修改和查询. 因此,这道题我们要往子树上靠. 我们首先从1号点进行dfs遍历,顺便求出点的dfs序和深度,然后我们采用倍增的思想,可以 ...

  8. Codeforces 343D Water Tree(DFS序 + 线段树)

    题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...

  9. [CodeForces877 E. Danil and a Part-time Job]dfs序+线段树

    [CodeForces877 E.Danil and a Part-time Job]dfs序+线段树 分类:Data Structure SegMent Tree dfn 1. 题目链接 [Code ...

最新文章

  1. python编写脚本方法_【Python】教你一步步编写banner获取脚本
  2. iOS scrollToItemAtIndexPath 无效的解决方案
  3. Spring - Java/J2EE Application Framework 应用框架
  4. BaseActivity的抽取
  5. android6.0源码分析之AMS服务源码分析
  6. CodeForces - 888G Xor-MST(贪心+字典树+最小生成树)
  7. C语言高级编程:数组指针与数组
  8. 线索二叉树的C语言实现
  9. 【Python】数据转换利器
  10. springboot 上传文件保存在本地磁盘
  11. Site-Site Ipsec ×××配置和验证
  12. Spring Boot系列(一)——初识Spring Boot
  13. 计算机一级在线考试软件,全国计算机等级考试一级MS OFFICE练习软件
  14. 一份某品牌天猫专卖店运营计划书
  15. 09、Non-Black-Box ZK(Barak‘s protocol)--Alon Rosen
  16. 滴滴竟然已经投资了这么多公司?
  17. Hive 异常,长期更新帖
  18. 债务人无力偿还,债权人可否直接起诉“次债务人”
  19. Podman一篇就学会
  20. python实现简单的神经网络,python的神经网络编程

热门文章

  1. IOS之使用纯代码push ViewController
  2. IOS基础之Foundation框架常用类NSFileManager,DSDate,CGPoint,CGSize,copy,单例
  3. java actor和线程有什么区别_Scala Actor与java并发编程的区别
  4. java 访问私有成员,在Java中访问私有方法?
  5. 程序员基本功10栈和队列
  6. linux 目录大小是12288,为什么有些目录数的引用超过3,为什么很多目录的大小都是4096...
  7. vue中如何解决touch和click共存的问题
  8. QStyleOptionGraphicsItem实现自绘按钮悬浮按下状态
  9. Android开发之设置Edittext小数点后两位以及限制位数同时使用
  10. 前后端分离与前后端不分离的区别