题目大意:
  给定一个$n(n\le10^5)$个结点的树,初始全为白点。$m(m\le10^5)$次操作,每次将点$x$染成黑色或询问从$x$出发至少经过一个黑点能到达的点中,编号次大的点。

思路:
  将操作倒序处理,即原操作变为擦除颜色和询问两种操作。用并查集维护白点连通块和若干单独的黑点。记录每个连通块或黑点出发至少经过一个黑点能到达的点中,能到达的最大和次大的点。擦除黑点时进行合并即可。维护最大、次大点时选择答案较小的连通块暴力递减。递减次数加起来是$n$。初始时每个连通块维护的最大值都是$n$,次大值都是$n-1$。而只有当连通块的点中含有$n$或$n-1$时,答案才会变小。每次合并时从两个连通块中答案比较小的往下枚举,总共最多枚举$2n$次。时间复杂度$O((n+m)\alpha(n)$比标算不知道高到哪里去了。

 #include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=1e5+,M=1e5+;
struct Edge {
int to,next;
};
Edge e[N<<];
int h[N],b[N],ans[N];
inline void add_edge(const int &u,const int &v) {
e[++h[]]=(Edge){v,h[u]};h[u]=h[];
e[++h[]]=(Edge){u,h[v]};h[v]=h[];
}
std::pair<bool,int> q[M];
struct DisjointSet {
int anc[N];
void reset(const int &n) {
for(register int i=;i<=n;i++) anc[i]=i;
}
int find(const int &x) {
return x==anc[x]?x:anc[x]=find(anc[x]);
}
void merge(const int &x,const int &y) {
anc[find(x)]=find(y);
}
bool same(const int &x,const int &y) {
return find(x)==find(y);
}
};
DisjointSet s;
std::pair<int,int> max[N];
inline void maintain(const int &x) {
while(max[x].first&&s.same(x,max[x].first)) max[x].first--;
max[x].second=std::max(std::min(max[x].second,max[x].first-),);
while(max[x].second&&s.same(x,max[x].second)) max[x].second--;
}
int main() {
for(register int T=getint();T;T--) {
const int n=getint(),m=getint();
std::fill(&h[],&h[n]+,-);
for(register int i=;i<n;i++) {
add_edge(getint(),getint());
}
for(register int i=;i<=m;i++) {
const bool opt=getint()&;
const int x=getint();
if(opt&&!b[x]) b[x]=i;
q[i]={opt,x};
}
s.reset(n);
std::fill(&max[],&max[n]+,std::make_pair(n,n-));
for(register int i=;i<=n;i++) {
if(!b[i]) maintain(i);
}
for(register int x=;x<=n;x++) {
if(b[x]) continue;
for(register int i=h[x];~i;i=e[i].next) {
const int &y=e[i].to;
if(b[y]||s.same(x,y)) continue;
max[s.find(y)]=std::min(max[s.find(y)],max[s.find(x)]);
s.merge(x,y);
maintain(s.find(x));
}
}
for(register int i=m;i;i--) {
const bool opt=q[i].first;
const int x=q[i].second;
if(opt&&b[x]==i) {
b[x]=;
maintain(s.find(x));
for(register int i=h[x];~i;i=e[i].next) {
const int &y=e[i].to;
if(b[y]||s.same(x,y)) continue;
max[s.find(y)]=std::min(max[s.find(y)],max[s.find(x)]);
s.merge(x,y);
maintain(s.find(x));
}
}
if(!opt) {
ans[i]=max[s.find(x)].second?:-;
}
}
for(register int i=;i<=m;i++) {
if(!q[i].first) printf("%d\n",ans[i]);
}
}
return ;
}

[CodeChef-LVGFT]Lovers Gift的更多相关文章

  1. USACO . Greedy Gift Givers

    Greedy Gift Givers A group of NP (2 ≤ NP ≤ 10) uniquely named friends has decided to exchange gifts ...

  2. 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树

    3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1288  Solved: 490 ...

  3. CF# Educational Codeforces Round 3 B. The Best Gift

    B. The Best Gift time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  4. 【BZOJ4260】 Codechef REBXOR 可持久化Trie

    看到异或就去想前缀和(⊙o⊙) 这个就是正反做一遍最大异或和更新答案 最大异或就是很经典的可持久化Trie,从高到低贪心 WA: val&(1<<(base-1))得到的并不直接是 ...

  5. 快来玩“Gift大转盘”百分百赚好礼

    现在开始到今年的最后一天,你天天都可以来转100%中奖的“ Gift大转盘 ”.代金券.产品折扣.精美纪念礼,没有多余规则.全部网友都可参加,转到就是你赚到,赶快转起来吧! >>活动主页& ...

  6. Gift Hunting(分组背包)

    Gift Hunting Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...

  7. codechef 两题

    前面做了这场比赛,感觉题目不错,放上来. A题目:对于数组A[],求A[U]&A[V]的最大值,因为数据弱,很多人直接排序再俩俩比较就过了. 其实这道题类似百度之星资格赛第三题XOR SUM, ...

  8. Codeforces Educational Codeforces Round 3 B. The Best Gift 水题

    B. The Best Gift 题目连接: http://www.codeforces.com/contest/609/problem/B Description Emily's birthday ...

  9. codechef January Challenge 2014 Sereja and Graph

    题目链接:http://www.codechef.com/JAN14/problems/SEAGRP [题意] 给n个点,m条边的无向图,判断是否有一种删边方案使得每个点的度恰好为1. [分析] 从结 ...

随机推荐

  1. DIV的变高与变宽

    代码: <!DOCTYPE HTML><html><head> <meta charset="utf-8"> <title&g ...

  2. Xamarin+vs2010部署错误:error MSB6004: 指定的任务可执行文件位置\sdk\\tools\zipalign.exe”无效

    好不容易配好了Xamarin和vs2010,也搞好了GenyMotion的虚拟机配置,开始调试的时候又报出了这样的错误: error MSB6004: 指定的任务可执行文件位置"C:\Use ...

  3. 帮助小伙伴写的组装xml字符串类

    import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; import java.uti ...

  4. 【EOJ3654】管理孩子(贪心,二分)

    题意:有一棵n个点的树,其中有k个是关键点,将树分割成若干部分,每部分至少包含一个关键点,求最大分割大小的最小值 思路: 最后特判一下f[1]的值 #include<cstdio> #in ...

  5. HDU1003MAX SUM (动态规划求最大子序列的和)

    Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  6. Linux下程序对拍_C++ (付费编号1001)

    本博客为精品博客,涉及利益问题,严禁转载,违者追究法律责任 一.对拍背景 对拍是一种十分实用的检查程序正确性的手段,在比赛时广泛使用 我们一般对拍两个程序,一个是自己不确定正确性的高级算法,另一个一般 ...

  7. bzoj 1016 深搜

    首先我们知道MST的一些性质,对于这道题来说就是,假设我们先求出一颗MST设为G,由已知边权相同的边最多会有10条,那么假设我们在这10条边中选取size条边∈G,那么我们在这边权相同的边集E中任意选 ...

  8. word2vec 理论与实践

    导读 本文简单的介绍了Google 于 2013 年开源推出的一个用于获取 word vector 的工具包(word2vec),并且简单的介绍了其中的两个训练模型(Skip-gram,CBOW),以 ...

  9. 自动化测试===【转】Robot Framework作者建议如何选择自动化测试框架

    原文:http://www.infoq.com/cn/news/2012/06/robot-author-suggest-autotest 软件自动化测试,作为手工测试的替代,越来越受到关注.Pekk ...

  10. html怎样让表格里面的内容居中

    html怎样让表格里面的内容居中 text-align:center; 在表格td中,有两个属性控制居中显示 align——表示左右居中——left,center,right valign——控制上下 ...