{题解}[jzoj5097]【GDOI2017 day1】取石子游戏
来源:互联网 发布:淘宝店花呗怎么开通 编辑:程序博客网 时间:2024/06/13 09:57
传送门
Description
五千字的满分作文题目……
大概只有两句话
给出一棵以 1 为根带权有根树
求 对于每个点 除它的子树以外结点权值的mex
Solution
画一棵树 我们发现
对于一个点 若其 ans 为 0 则它子树以外不出现 0
同理非零情况
那么 对于所有相同权值的结点的 LCA 到根的路径上 ans 都可能取这个权值
一个显然的做法是 从小到大枚举权值 做 LCA
这样的做法是足够优秀的 LCA 可以用 Tarjan 实现 倍增也够用了
Code
#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define oo 2139062143#define sqr(x) ((x)*(x))#define lowbit(x) ((x)&(-x))#define abs(x) (((x)>=0)?(x):(-(x)))#define max(x,y) (((x)>(y))?(x):(y))#define min(x,y) (((x)<(y))?(x):(y))#define fo(i,x,y) for (int i = (x);i <= (y);++ i)#define fd(i,x,y) for (int i = (x);i >= (y);-- i)#define fm(i,x) for (int i = las[x];i;i = nex[i])using namespace std;typedef double db;typedef long long ll;const int N = 1001000;int n,m,cas;int x,y;int las[N],last[N],nex[N],a[N],tot;int f[N][21],dep[N];int bz[N],az[N],los[N],ans[N],du[N],d[N];int read(){ 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 link(int x,int y){ last[++ tot] = y, nex[tot] = las[x], las[x] = tot;}void bfs(){ int i,head = 0,tail = 0,x; fo(i,1,n) if (!du[i]) d[++ tail] = i; dep[1] = 1; while (head < tail) { x = d[++ head]; fm(i,x) { -- du[last[i]]; if (!du[last[i]]) d[++ tail] = last[i]; f[last[i]][0] = x; dep[last[i]] = dep[x] + 1; } }}int lca(int x,int y){ if (dep[x] < dep[y]) swap(x,y); fd(i,20,0) if (dep[f[x][i]] > dep[y]) x = f[x][i]; if (dep[x] != dep[y]) x = f[x][0]; fd(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]; else return x;}int main(){ freopen("game.in","r",stdin); freopen("game.out","w",stdout); for (scanf("%d", &cas);cas;cas --) { tot=0; memset(las,0,sizeof(las)); memset(bz,0,sizeof(bz)); memset(ans,255,sizeof(ans)); memset(du,0,sizeof(du)); scanf("%d%d", &n, &m); fo(i,1,n) a[i] = read(); fd(i,n,1) los[i] = bz[a[i]],bz[a[i]] = i; fo(i,1,n - 1) { int x = read(),y = read(); link(x,y); ++ du[y]; } 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 (ans[j] == -1) ans[j] = i; break; } while (x) { if (!y) y = x; else y = lca(y,x); x = los[x]; } while (y && ans[y] == -1) ans[y] = i,y = f[y][0]; } fo(i,1,n) { if (ans[i] == -1) printf("0 "); else printf("%d ",ans[i]); } printf("\n"); }}
阅读全文
1 0
- {题解}[jzoj5097]【GDOI2017 day1】取石子游戏
- 【JZOJ5097】【GDOI2017 day1】取石子游戏
- 【GDOI2017 day1】取石子游戏
- 【GDOI2017 Day 1 T2】取石子游戏
- 【GDOI 2017 day1】取石子游戏
- bzoj 1874 取石子游戏 题解 & SG函数初探
- HDU 2177 取(2堆)石子游戏题解
- 【GDOI2017模拟二试4.12】石子游戏
- 石子游戏kam题解
- "取石子"游戏
- 取石子游戏
- 取石子游戏
- 取石子游戏
- POJ1067取石子游戏
- PKU1067 取石子游戏
- 取石子游戏
- 取石子游戏
- 1067 取石子游戏
- C++实验6
- jQuery中.bind() .live() .delegate() .on()区别
- Handler详解
- AndroidStudio2.3.2升级后工程打开失败解决
- Spark实战之读写HBase
- {题解}[jzoj5097]【GDOI2017 day1】取石子游戏
- mysql数据表操作
- jsp杂记
- Thinking in Java 笔记
- 常用排序算法总结(插入、冒泡、快速,堆、选择、希尔、归并)
- JS处理包含readonly属性的下拉框直接赋值
- wordexp函数学习
- js原型链demo
- 关于项目中用easyUI建tab页的一些东西