【GDOI2017 day1】取石子游戏
来源:互联网 发布:mac 10.11.6 升级包 编辑:程序博客网 时间:2024/06/05 02:01
Description
题意简单一点:给出一棵树,让你求出每个节点的子树以外的mex(最小没出现过的自然数)
Solution
比赛的时候没有看懂,就没敢去打,其实思想很简单。
对于一个序列来说,包含一个x的区间答案肯定不是x。
那么我们把这个想法放到树上。
对于颜色x,我们提取出来,求出他们的lca(求lca是满足结合律的),假设这个lca为y,那么很显然的除了y这个子树,其他的子树都没有x这个颜色了。现在我们要求的是子树之外的mex,那么包含y这个子树的只有y到根路径上的节点。
那么我们现在从小到大枚举颜色,求出lca后,一个个往上跳,假如当前这个节点已经被标记过颜色了,那么就可以break掉,否则就标色。因为从小到大,肯定满足最小。
Code
#include<iostream>#include<stdio.h>#include<algorithm>#include<math.h>#include<string.h>#define fo(i,a,b) for(i=a;i<=b;i++)#define fod(i,a,b) for(i=a;i>=b;i--)#define rep(i,a) for(i=first[a];i;i=next[i])using namespace std;const int maxn=1e6+7;int i,j,k,l,t,n,m,ans,cas,x,y;int first[maxn],last[maxn],next[maxn],a[maxn],num;int f[maxn][21],deep[maxn];int bz[maxn],az[maxn],hou[maxn],an[maxn],du[maxn],d[maxn];int get(){ char ch=getchar();int x=0; while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); return x;}void add(int x,int y){ last[++num]=y,next[num]=first[x],first[x]=num;}void bfs(){ int i,head=0,tail=0,x; fo(i,1,n)if(!du[i])d[++tail]=i;deep[1]=1; while(head<tail){ x=d[++head]; rep(i,x){ du[last[i]]--;if(!du[last[i]])d[++tail]=last[i]; f[last[i]][0]=x;deep[last[i]]=deep[x]+1; } }}int lca(int x,int y){ int i;if(deep[x]<deep[y])swap(x,y); fod(i,20,0)if(deep[f[x][i]]>deep[y])x=f[x][i]; if(deep[x]!=deep[y])x=f[x][0]; fod(i,20,0)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i]; if(x!=y)return f[x][0];return x;}int main(){ freopen("game.in","r",stdin); freopen("game.out","w",stdout); for(scanf("%d",&cas);cas;cas--){ num=0,memset(first,0,sizeof(first));memset(bz,0,sizeof(bz)); memset(an,255,sizeof(an));memset(du,0,sizeof(du)); scanf("%d%d",&n,&m); fo(i,1,n)a[i]=get(); fod(i,n,1){ hou[i]=bz[a[i]];bz[a[i]]=i; } fo(i,1,n-1)k=get(),l=get(),add(k,l),du[l]++; bfs();fo(j,1,20)fo(i,1,n)f[i][j]=f[f[i][j-1]][j-1]; fo(i,0,m){ x=bz[i];y=0; if(!x){ fo(j,1,n)if(an[j]==-1)an[j]=i;break; } while(x){ if(!y)y=x; else y=lca(y,x); x=hou[x]; } while(y&&an[y]==-1)an[y]=i,y=f[y][0]; } fo(i,1,n){if(an[i]==-1)an[i]=0;printf("%d ",an[i]);} printf("\n"); }}
1 0
- 【GDOI2017 day1】取石子游戏
- 【JZOJ5097】【GDOI2017 day1】取石子游戏
- {题解}[jzoj5097]【GDOI2017 day1】取石子游戏
- 【GDOI2017 Day 1 T2】取石子游戏
- 【GDOI 2017 day1】取石子游戏
- 【GDOI2017模拟二试4.12】石子游戏
- "取石子"游戏
- 取石子游戏
- 取石子游戏
- 取石子游戏
- POJ1067取石子游戏
- PKU1067 取石子游戏
- 取石子游戏
- 取石子游戏
- 1067 取石子游戏
- PKU1067(取石子游戏)
- 1679 取石子游戏
- 1773 取石子游戏
- 数据访问层
- MP4容器格式
- MIME
- 初窥Shell 脚本
- 多媒体封装格式详解---MKV
- 【GDOI2017 day1】取石子游戏
- git的常用命令
- Git添加远程仓库
- php中echo、print、print r、var_dump的区别
- JavaScript中数组的迭代方法:forEach、map、filter、reduce、every、some
- 一个成功的Git分支模型
- Git托管网站
- 给git pull默认加上rebase功能
- 基于Linux下的GTK+2.0贪吃蛇游戏开发