题意:给你一棵n个点的树。m个操作,op 1:在点i上建立银行。op 2:询问从点x开始可以经过至少一个银行走到的点中编号第二大的点。

n,m<=1e5.

标程:

 #include<bits/stdc++.h>
using namespace std;
int read()
{
int x=;char ch=getchar();
while (ch<''||ch>'') ch=getchar();
while (''<=ch&&ch<='') x=(x<<)+(x<<)+ch-'',ch=getchar();
return x;
}
const int N=;
set<int,greater<int> > s;
set<int,greater<int> >::iterator it;
int cnt,head[N],Mx[N],Mxc[N],f[N],tot,ans[N],tag[N],u,v,n,m;
struct node{int to,next;}num[N*];
struct _node{int op,x;}q[N];
void add(int x,int y)
{num[++cnt].to=y;num[cnt].next=head[x];head[x]=cnt;}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
void merge(int x,int y)
{
if (x==y) return;
s.erase(Mx[x]);s.erase(Mx[y]);
s.erase(Mxc[x]);s.erase(Mxc[y]);
if (Mx[x]>Mx[y]) Mxc[y]=Mx[y],Mx[y]=Mx[x];//注意最大次大的传递
else if (Mx[x]>Mxc[y]) Mxc[y]=Mx[x];
if (Mxc[x]>Mxc[y]) Mxc[y]=Mxc[x];
s.insert(Mx[y]);s.insert(Mxc[y]);
f[x]=y;
}
void dfs(int x,int fa)
{
if (tag[x]) s.insert(x);//银行作为单点也要加入
for (int i=head[x];i;i=num[i].next)
if (num[i].to!=fa)
{
dfs(num[i].to,x);
if (!tag[num[i].to]&&!tag[x]) merge(find(num[i].to),find(x));
}
}
int qry(int x)
{
int fl=;x=find(x);
for (it=s.begin();it!=s.end();++it)
{
if (*it==Mx[x]||*it==Mxc[x]) continue;
if (!fl) fl=;else return *it;
}
return -;
}
int main()
{
n=read();m=read();tot=;s.clear();
memset(head,,sizeof(head));cnt=;
for (int i=;i<n;i++) u=read(),v=read(),add(v,u),add(u,v);
for (int i=;i<=n;i++) f[i]=i,Mx[i]=i,Mxc[i]=,s.insert(i);
for (int i=;i<=m;i++)
{
q[i].op=read(),q[i].x=read();
if (q[i].op==) tag[q[i].x]++;//有可能被该银行被统计多次
}
dfs(,-);
for (int i=m;i>=;i--)
{
if (q[i].op==)
{
int now=find(q[i].x);tag[q[i].x]--;
if (!tag[q[i].x])
for (int j=head[q[i].x];j;j=num[j].next)
if (!tag[num[j].to]) merge(find(num[j].to),now);
}else ans[++tot]=qry(q[i].x);
}
while (tot) printf("%d\n",ans[tot--]);
return ;
}

题解:并查集+技巧

暴力可以过很多啊,倒着枚举编号点,判断x和该编号点的路径上是否有银行,树链剖分+线段树(lct)维护即可。

因为连通块拆分比较麻烦,考虑倒着执行操作,相当于删去银行。每删去一个银行就相当于把若干个连通块合并。

询问即是问除了x点所在连通块其他部分的第二大。维护一个保存每个连通块最大次大的set,取出不等于当前连通块最大次大的第二大元素,最多取4次即可。

时间复杂度O((n+m)(logn+a(n))。

soj97 旅行的更多相关文章

  1. BZOJ 3531: [Sdoi2014]旅行 [树链剖分]

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1685  Solved: 751[Submit][Status] ...

  2. vijos P1780 【NOIP2012】 开车旅行

    描述 小\(A\)和小\(B\)决定利用假期外出旅行,他们将想去的城市从\(1\)到\(N\)编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市\(i\)的海拔高度为 ...

  3. 【BZOJ-1570】BlueMary的旅行 分层建图 + 最大流

    1570: [JSOI2008]Blue Mary的旅行 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 388  Solved: 212[Submit ...

  4. codevs 1036 商务旅行(Targin求LCA)

    传送门 Description 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇之间都有道路连接,任意 ...

  5. nyoj 71 独木舟上的旅行(贪心专题)

    独木舟上的旅行 时间限制:3000 ms  |  内存限制:65535 KB 难度:2   描述 进行一次独木舟的旅行活动,独木舟可以在港口租到,并且之间没有区别.一条独木舟最多只能乘坐两个人,且乘客 ...

  6. 【bzoj3531】 [SDOI2014]旅行

    题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰.为了方便,我们 ...

  7. tomcat源码分析(三)一次http请求的旅行-从Socket说起

    p { margin-bottom: 0.25cm; line-height: 120% } tomcat源码分析(三)一次http请求的旅行 在http请求旅行之前,我们先来准备下我们所需要的工具. ...

  8. 11.14 T2 小x的旅行(小x的旅行)

    1.小x的旅行   (travel.pas/c/cpp) [问题描述] 小x大学毕业后,进入了某个公司做了高层管理,他每年的任务就是检查这个公司在全国各地N个分公司的各种状况,每个公司都要检查一遍,且 ...

  9. hdoj 2066 一个人的旅行

    Problem Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰 ...

随机推荐

  1. 对A盾原理的小小总结,膜拜A神

    A盾的原理是在驱动加载时重载os内核,获取原始ssdt表的地址. 应用层点击查询的代码在文件A-ProtectView.cpp中,每种点击操作调用相应的 query查询函数,在query函数里 Rea ...

  2. How to Add Swap on CentOS

    About Linux Swapping Linux RAM is composed of chunks of memory called pages. To free up pages of RAM ...

  3. [21]APUE:线程同步之记录锁(文件)

    [a] 概念 建议锁:在遵循相同记录锁规则的进程/线程间生效,通常用于保证某个程序自身多个进程/线程间的数据一致性 强制锁:意在保证所有进程间的数据一致性,但不一定有效:如不能应对先 unlink 后 ...

  4. 如何在html中添加视频

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="445" heig ...

  5. Dede没见过的漏洞

    payload:plus/search.php?keyword=xxx&arrs1[]=99&arrs1[]=102&arrs1[]=103&arrs1[]=95&am ...

  6. fso文件夹操作用法实操

    Sub 订单转换()Application.ScreenUpdating = FalseOn Error Resume Next Dim fso, fl, m%, n%, p%, q& Dim ...

  7. [java]反转单项链表,用O(n)时间和O(1)空间

    链表数据结构 public class ListNode { public int val; public ListNode next; public ListNode(int x) { val = ...

  8. sslforfree的证书合并成类似于certbot的ssl证书文件

    之前的證書都是通過 certbot的命令生成的,但是目前一個服務器太多個網站,太多個ssl證書,證書過期之後,目前是 通過 ssl for free 網站再生成新的 ssl證書,再次更新證書週期 Le ...

  9. [JZOJ3234] 阴阳

    题目 题目大意 有一棵树,每条边有\(0\)或\(1\)两种颜色. 求满足存在\((u,v)\)路径上的点\(x\)使得\((u,x)\)和\((x,v)\)路径上的两种颜色出现次数相同的点对\((u ...

  10. php获取本周、本月、本年的时间段

    这是在TP框架里面自己用到的一个获取周.月.年时间段的方法.