树 (罗雨屏)

来源:互联网 发布:淘宝一天能刷多少单 编辑:程序博客网 时间:2024/05/22 15:49
试题来源
  IOI2012中国国家队训练
问题描述
  给定一棵大小为 n 的有根点权树,支持以下操作:
  • 换根
  • 修改点权


  • 查询子树最小值
输入格式
  第一行两个整数 n, Q ,分别表示树的大小和操作数。
  接下来n行,每行两个整数f,v,第i+1行的两个数表示点i的父亲和点i的权。保证f < i。如 果f = 0,那么i为根。输入数据保证只有i = 1时,f = 0。



  接下来 m 行,为以下格式中的一种:
  • V x y表示把点x的权改为y

  • E x 表示把有根树的根改为点 x




  • Q x 表示查询点 x 的子树最小值
输出格式
  对于每个 Q ,输出子树最小值。
样例输入
3 7
0 1
1 2
1 3
Q 1
V 1 6
Q 1
V 2 5
Q 1
V 3 4
Q 1
样例输出
1
2
3
4
数据规模和约定
  对于 100% 的数据:n, Q ≤ 10^5。



题目大意就是给你一棵树,支持换根、修改点权、求一个点的子树的最小值。

对于这道题,如果没有换根操作,就直接上RMQ。

然而有了换根,我们可以先以1号点为根处理出这棵树的dfs序用线段树来维护一段dfs序的最小值,修改点权就不说了。

对于每个查询

设查询的点X;

设此时根为R;

设L[X]代表X在dfs序中第一次出现的位置

设R[X]代表X在dfs序中第一次出现的位置

如图的一棵树

1:当X等于R时 比如X=R=1

直接输出整棵树的最小值。



2:当R不在X的子树中 比如X=2 R=3

明显就是X的子树中的最小值

即为L[X]到R[X]的最小值



3:当X是R的祖先时

首先确定包含点的范围:

举两个例子:当X=2、R=4时是1、2、3、5 当X=1、R=4时是1、3。

通过这两个例子,我们可以看出包含的范围就是整棵树除去E所在的子树(E是X的儿子,也是R的祖先)。

那么答案就是L[1]到L[E]-1与R[E]+1到R[1]的最小值

(这一点要仔细想想,当初也是花了好久才弄懂)

最后说一下几个要注意的地方吧

求dfs序,不能直接dfs,会爆栈,所以。。。。手动栈吧

找E的时候不能一步一步往上跳,用倍增吧

Ps:其实上面两点都不要管就可以过原始数据,只是我们oj丧心病狂处处卡人啊。。。。


附代码

#include<cstdio>#include<iostream>#include<cmath>const double eps=0.0000001;const int maxn=100010*2,maxm=maxn*8;using namespace std;int tot=0;int pre[maxn],son[maxn];int now[maxn];void add(int a,int b){pre[++tot]=now[a];now[a]=tot;son[tot]=b;}inline int read(){    char ch=getchar(); int tmp=0;    while (ch<'0' || ch>'9') ch=getchar();    for (;ch<='9' && ch>='0';ch=getchar()) tmp=tmp*10+ch-'0';    return tmp;}int n,m;int a[maxn];void init(){n=read();m=read();for (int i=1;i<=n;++i){int a=read();int b=read();add(a,i);::a[i]=b;}}int l[maxn],r[maxn];int dep[maxn];int sum=0;int maxdep=0;int fa[maxn][40];int num[maxn];int syssta[maxn];int bre[maxn];void dfs(){int tot=0;syssta[++tot]=1;dep[1]=1;for (int i=1;i<=n;++i)bre[i]=now[i];while (tot){if (bre[syssta[tot]]==now[syssta[tot]]){l[syssta[tot]]=++sum;num[sum]=a[syssta[tot]];}if (!bre[syssta[tot]]){r[syssta[tot]]=++sum;num[sum]=a[syssta[tot]];tot--;}else {syssta[tot+1]=son[bre[syssta[tot]]];fa[son[bre[syssta[tot]]]][0]=syssta[tot];bre[syssta[tot]]=pre[bre[syssta[tot]]];dep[syssta[tot+1]]=dep[syssta[tot]]+1;maxdep=max(maxdep,dep[syssta[tot+1]]);tot++;}}}void prepare(){int quit=(int)(log(maxdep)/log(2)+eps);for (int i=1;i<=quit;++i)for (int j=1;j<=n;++j)fa[j][i]=fa[fa[j][i-1]][i-1];}inline int find(int x,int root){swap(x,root);int gap=dep[x]-dep[root]-1;while (gap){int tmp=(int)(log(gap)/log(2)+eps);x=fa[x][tmp];gap-=1<<tmp;}return x;}int tree[maxm];void inline updata(int p){int Ls=p*2,Rs=Ls+1;tree[p]=tree[Ls]<tree[Rs]?tree[Ls]:tree[Rs];}int wh[maxn];void build(int p,int l,int r){if (l==r){tree[p]=num[l];wh[l]=p;return;}int mid=(l+r)/2;build(p*2,l,mid);build(p*2+1,mid+1,r);updata(p);}void ins(int p,int add){tree[p]=add;p=p>>1;while (p){updata(p);p=p>>1;}}inline int min(int a,int b){return a<b?a:b;}int countit(int p,int l,int r,int fir,int las){if (l==fir && r==las)return tree[p];int mid=(l+r)/2;int Ls=p*2,Rs=Ls+1;if (las<=mid) return countit(Ls,l,mid,fir,las);if (fir>mid) return countit(Rs,mid+1,r,fir,las);int ans=countit(Ls,l,mid,fir,mid);ans=min(ans,countit(Rs,mid+1,r,mid+1,las));return ans;}void work(){dep[1]=1;dfs();prepare();n*=2;build(1,1,n);int root=1;while (m--){char tmp[3];scanf("%s",tmp);if (tmp[0]=='V'){int a=read();int b=read();ins(wh[l[a]],b);ins(wh[r[a]],b);}if (tmp[0]=='E')root=read();if (tmp[0]=='Q'){int x=read();int ans;if (x==root) ans=tree[1];elseif (l[x]>l[root] || r[x]<r[root]) ans=countit(1,1,n,l[x],r[x]);else{int xx=find(x,root);ans=min(countit(1,1,n,1,l[xx]-1),countit(1,1,n,r[xx]+1,n));}printf("%d\n",ans);}}}int main(){init();work();return 0;}




原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 玩武装突袭3CPU不好怎么办? 户户通001信号中断怎么办 电脑运行速度特别慢怎么办 win8.1电脑太卡怎么办 电线厂非法战地没拆够怎么办 久笔记本电脑玩彩虹六号卡怎么办 彩虹六号一直建立小队进不去怎么办 小佩喂食器离线怎么办 手机打游戏掉帧怎么办 电脑打游戏掉帧怎么办 武装突袭3太卡怎么办 英语b级考不过怎么办 绝地求生被燃烧瓶烧了怎么办 搜狗输入法打字出现问好怎么办 全民k歌解码失败怎么办 视频声音小怎么办调大 乐视2视频声音小怎么办 录视频声音太小怎么办 显卡装了没反应怎么办 笔记本关闭核显黑屏怎么办 驱动补丁被卸了怎么办 网络驱动被删了怎么办 新装系统网卡没驱动怎么办 核显没有dp口怎么办 苹果7屏幕太小了怎么办 苹果装系统卡住了怎么办 苹果7手机白屏黑苹果怎么办 衣服破了个洞怎么办 黑苹果自带升级怎么办 双显卡都禁用了怎么办 win10优盘识别不出来怎么办 黑苹果无限重启怎么办 水泥地面起砂怎么办?这几招很有用 跟老公没法过了怎么办 胃和肠子有点烂怎么办? 车的屏幕黑了怎么办 ios12玩游戏闪退怎么办 没网steam要登录怎么办 电脑有gta还需要安装怎么办 孤岛惊魂5卡顿怎么办 酷匠密码忘记了怎么办