NEERC2017 Laminar Family 树链剖分+LCA

题目链接

http://codeforces.com/gym/101630/attachments/download/6401/20172018-acmicpc-northeastern-european-regional-contest-neerc-17-en.pdf

题意

给出一棵树和一组操作,操作的格式是给出uvu、v两个节点,并将该节点所确定的路径上的节点全部加入到一个新的集合里面去。
如果所有的集合中任意两个均满足,要么互相包含,要么不相交,则输出Yes,否则输出No。

题解

互相包含这个条件不太好用,因为它相当于是两个条件,因此我们对这个条件做一下操作:我们求出所有出现过的路径长度(求长度可以使用LCA来求),并将这些操作按照长度从大到小排序,这样的话集合的包含就只是一个方向的了,即已经出现过的集合包含当前的集合。这样对我们解决这道题有很大帮助。

我们在从长到短遍历路径的时候,先查看这条路径上的颜色是否多于一种,如果出现多种颜色,就说明当前的集合会与之前的集合有交叉,那么就输出No,否则的话,就把沿路的点全都染上一种新的颜色。

如果所有的路径都遍历完成,没有出现矛盾,那么输出Yes。

小问题:如何判定一条链上只有一种颜色呢?
我们可以用数字给颜色编号,然后检查这条链上的最大值和这条链上的最小值是否相等。

思路似乎很简单,这里有几个实现的细节:
1. 树链剖分对树上的点进行操作。
2. 线段树要求支持区间set值的操作,和区间询问最大最小值的操作。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <assert.h>
using namespace std;
#define pr(x) cout<<#x<<":"<<x<<endl
const int maxn = 2e5+7;
const int inf = 1e9;
int head[maxn];
int sz[maxn],fa[maxn],son[maxn],dep[maxn],top[maxn],w[maxn];
int pa[maxn][22];
int idx,cnt,n,m;
struct edge{int v,nxt;
}Es[maxn<<1];
struct segtree{int mxval[maxn<<2];int mival[maxn<<2];int tag[maxn<<2];void pushup(int rt){mxval[rt] = max(mxval[rt*2],mxval[rt*2+1]);mival[rt] = min(mival[rt*2],mival[rt*2+1]);}void pushdown(int rt){if(tag[rt]){mxval[rt*2] = mival[rt*2] = tag[rt];mxval[rt*2+1] = mival[rt*2+1] = tag[rt];tag[rt*2] = tag[rt*2+1] = tag[rt];tag[rt] = 0;}}void update(int rt,int l,int r,int ul,int ur,int val){if(l > ur || r < ul) return ;if(ul <= l && r <= ur){mxval[rt] = mival[rt] = val;tag[rt] = val;return ;}int mid = (l + r) / 2;pushdown(rt);update(rt*2,l,mid,ul,ur,val);update(rt*2+1,mid+1,r,ul,ur,val);pushup(rt);}pair<int,int> query(int rt,int l,int r,int ul,int ur){if(l > ur || r < ul) return {inf,-inf};if(ul <= l && r <= ur) return {mival[rt],mxval[rt]};pushdown(rt);int mid = (l+r)/2;pair<int,int> a = query(rt*2,l,mid,ul,ur);pair<int,int> b = query(rt*2+1,mid+1,r,ul,ur);return {min(a.first,b.first),max(a.second,b.second)};}
}seg;
void init(){idx = cnt = 0;memset(head,-1,sizeof(head));
}
void addedge(int i,int j){Es[cnt].v = j,Es[cnt].nxt = head[i],head[i] = cnt++;
}
void dfs1(int u,int f,int dp){son[u] = 0;fa[u] = f;dep[u] = dp;sz[u] = 1;for(int e = head[u];e != -1;e = Es[e].nxt){int v = Es[e].v;if(v == fa[u]) continue;dfs1(v,u,dp+1);sz[u] += sz[v];if(sz[v] > sz[son[u]])son[u] = v;}
}void dfs2(int u,int tp){top[u] = tp;w[u] = ++idx;if(son[u]) dfs2(son[u],tp);else return ;for(int e = head[u];e != -1;e = Es[e].nxt){int v = Es[e].v;if(v == son[u] || v == fa[u]) continue;dfs2(v,v);}
}bool getp(int u,int v){pair<int,int> pans = {inf,-inf};int fu = top[u],fv = top[v];while(fu != fv){if(dep[fu] < dep[fv])swap(fu,fv),swap(u,v);auto p = seg.query(1,1,n,w[fu],w[u]);u = fa[fu];fu = top[u];pans.first = min(pans.first,p.first);pans.second = max(pans.second,p.second);}if(u == v) {auto p = seg.query(1,1,n,w[u],w[u]);return min(p.first,pans.first) == max(p.second,pans.second);}if(dep[u] < dep[v]) swap(u,v);auto p = seg.query(1,1,n,w[v],w[u]);return min(pans.first,p.first) == max(pans.second,p.second);
}
void modify(int u,int v,int x){int fu = top[u],fv = top[v];while(fu != fv){if(dep[fu] < dep[fv])swap(fu,fv),swap(u,v);seg.update(1,1,n,w[fu],w[u],x);u = fa[fu];fu = top[u];}if(u == v) {seg.update(1,1,n,w[u],w[u],x);return ;}if(dep[u] < dep[v]) swap(u,v);seg.update(1,1,n,w[v],w[u],x);
}
int lca(int u,int v){if(dep[u] < dep[v]) swap(u,v);int d = dep[u] - dep[v];for(int i = 0;i <= 20;++i) if(d & (1<<i)) u = pa[u][i];for(int i = 20;i >= 0;--i){if(pa[u][i] == pa[v][i]) continue;u = pa[u][i],v = pa[v][i];}if(u != v) u = pa[u][0],v = pa[v][0];assert(u == v); return u;
}
int uu[maxn],vv[maxn],dd[maxn],ss[maxn];
int main(){init();cin>>n>>m;for(int i = 0;i < n-1;++i){int u,v;scanf("%d%d",&u,&v);addedge(u,v);addedge(v,u);}dfs1(1,1,0);dfs2(1,1);for(int i = 1;i <= n;++i) pa[i][0] = fa[i];for(int t = 1;t <= 20;++t) for(int i = 1;i <= n;++i){pa[i][t] = pa[pa[i][t-1]][t-1];}for(int i = 0;i < m;++i){int u,v,d;scanf("%d%d",&u,&v);d = dep[u] + dep[v] - 2*dep[lca(u,v)]+1;uu[i] = u,vv[i] = v,dd[i] = d,ss[i] = i;} sort(ss,ss+m,[](int a,int b){return dd[a] > dd[b];});for(int i = 0;i < m;++i){int id = ss[i];//pr(uu[id]);pr(vv[id]);if(!getp(uu[id],vv[id])){return 0*puts("No");}modify(uu[id],vv[id],i+1);}puts("Yes");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/321142.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CF1009F-Dominant Indices【长链剖分】

正题 题目链接:https://www.luogu.com.cn/problem/CF1009F 题目大意 以1为根的一棵树&#xff0c;对于每个节点xxx求一个最小的kkk使得以xxx为根的子树中第kkk层的结点最多。 解题思路 我们先进行一次长链剖分&#xff0c;对于一个长链我们可以发现如果每次往下做的话&#…

VS2017 15.8第二个预览版本提升了对CPU Profiling和F#的支持

VS2017 15.8第一个预览版本的特性包括对ARM64构建的支持、ASP.NET Core对Docker的支持以及重新引入LibMan。在15.8的第二个预览版本中&#xff0c;微软发布了一个新Google Android模拟器的预览功能&#xff0c;它能够与Hyper-V兼容。这样的话&#xff0c;最新的Android模拟器就…

【SPFA】腾讯大战360

腾讯大战360 题目大意&#xff1a; 有n个点&#xff0c;还有m条线连接着这些点&#xff0c;有两个人在其中两个点上&#xff0c;让这两个人相遇最快要多久 原题&#xff1a; 题目描述 2010年11月3日&#xff0c;是一个难忘的日子。 腾讯发布消息&#xff1a;存360则&#…

一道有趣的最短路 NEERC2017 Journey from Petersburg to Moscow

题目链接 http://codeforces.com/gym/101630/attachments/download/6401/20172018-acmicpc-northeastern-european-regional-contest-neerc-17-en.pdf 题意 求11到n" role="presentation" style="position: relative;">nn的最短路&#xff0c;最…

P5904-[POI2014]HOT-Hotels加强版【长链剖分,dp】

正题 题目链接:https://www.luogu.com.cn/problem/P5904 题目大意 nnn个点的一棵树&#xff0c;求有多少个点对(i,j,k)(i,j,k)(i,j,k)使得这三个点距离相等。 解题思路 有两种情况&#xff0c;一是iii是j,kj,kj,k的祖先&#xff0c;二是i,j,ki,j,ki,j,k互相没有祖先关系 考虑…

初一级模拟试题总结(2019.3.2)

成绩 rank算上了其他大佬 rankrankranknamenamenamescorescorescoreT1T1T1T2T2T2T3T3T3T4T4T4111lyflyflyf400400400100100100100100100100100100100100100111wjjwjjwjj280280280100100100808080000100100100111tjhtjhtjh200200200100100100000000100100100111fyfyfy200200200…

ASP.NET Core Razor生成Html静态文件

一、前言最近做项目的时候&#xff0c;使用Util进行开发&#xff0c;使用Razor写前端页面。初次使用感觉还是不大习惯&#xff0c;之前都是前后端分离的方式开发的&#xff0c;但是使用Util封装后的Angular后&#xff0c;感觉开发效率还是杠杠滴。二、问题在发布代码的时候&…

NEERC2017 Archery Tournament 线段树 新套路

题目链接 http://codeforces.com/gym/101630/attachments/download/6401/20172018-acmicpc-northeastern-european-regional-contest-neerc-17-en.pdf 题意 给出一些圆&#xff0c;这些圆圆心在x轴上方&#xff0c;且与x轴相切&#xff0c;任意时刻&#xff0c;不存在图上的…

P2178-[NOI2015]品酒大会【SA,并查集】

正题 题目链接:https://www.luogu.com.cn/problem/P2178 题目大意 长度为nnn的字符串&#xff0c;每个位置有一个权值。 如果对于q,pq,pq,p有sq,qr−1sp,pr−1s_{q,qr-1}s_{p,pr-1}sq,qr−1​sp,pr−1​那么就称q,pq,pq,p为rrr相似。 对于每个rrr求有多少对q,pq,pq,p是rrr相似…

【Floyed】【最短路】商店选址问题(ssl 1760)

商店选址问题 ssl 1760 题目大意&#xff1a; 有一些点&#xff0c;在一个点上按医院&#xff0c;有一个值就是这个点到其他点的最短路之和&#xff0c;问这个值最小是多少 原题&#xff1a; Description 给出一个城市的地图&#xff08;用邻接矩阵表示&#xff09;&…

一文看懂.NET的各种变体

曾几何时&#xff0c;我们只有一个.NET&#xff0c;叫作.NET Framework。如果想要开发.NET应用程序&#xff0c;只要使用.NET Framework即可&#xff0c;非常简单。几年之后&#xff0c;出现了.NET变种的寒武纪大爆发&#xff08;我们称之为“.NET大爆炸”&#xff09;&#xf…

Codeforces Gym - 100917 部分题解

A.Abstract Picture Gym - 100917A 分析&#xff1a;由于最后刷的一笔肯定使得某一行或者是某一列均为相同的颜色。 因此我们可以在一开始找到所有的行或者列&#xff0c;他们的颜色全都一样&#xff0c;把这样的行或列加入到队列里面去。 我们处理在队列里面的行或者列&…

【最短路】【Floyed】医院设置(ssl 1614)

医院设置 ssl 1614 题目大意&#xff1a; 有n个点&#xff0c;在一个点上安医院&#xff0c;使这个点到其他点的最短路之和最小 原题&#xff1a; Description 设有一棵二叉树&#xff08;如右图&#xff09;。其中&#xff0c;圈中的数字表示结点中居民的人口。圈边上数…

牛客练习赛69C-旅行【结论,最大生成树】

正题 题目链接:https://ac.nowcoder.com/acm/contest/7329/C 题目大意 disx,ydis_{x,y}disx,y​表示x,yx,yx,y的所有路径的最短的边的最大值。 求一个1∼n1\sim n1∼n的排列&#xff0c;使得∑i2ndisi,i−1\sum_{i2}^ndis_{i,i-1}∑i2n​disi,i−1​最大 解题思路 首先一定是…

拓展 NLog 优雅的输送日志到 Logstash

在上上篇博客通过对aspnetcore启动前配置做了一些更改&#xff0c;以及对nlog进行了自定义字段&#xff0c;可以把请求记录输送到mysql&#xff0c;正式情况可能不会这么部署。因为近期也在学习elk&#xff0c;所以就打算做一个实例&#xff0c;结合nlog把日志输送到logstash&a…

曼哈顿距离与切比雪夫距离的转化及prufer序列

目录 曼哈顿距离与切比雪夫距离的相互转化prufer序列 1. 曼哈顿距离 与 切比雪夫距离 的相互转化 曼哈顿距离 |x1−x2||y1−y2|max(x1−x2y1−y2,x1−x2−y1y2,−x1x2y1−y2,−x1x2−y1y2)|x1−x2||y1−y2|max(x1−x2y1−y2,x1−x2−y1y2,−x1x2y1−y2,−x1x2−y1y2)|x_1 - x…

初一模拟赛总结(2019.3.9)

成绩&#xff1a; rank算上了其他大佬 rankrankranknamenamenamescorescorescoreT1T1T1T2T2T2T3T3T3T4T4T4222lyflyflyf230230230100100100303030000100100100333hkyhkyhky909090000000000909090444fyfyfy808080000606060000202020444whdwhdwhd808080202020606060000000666lth…

牛客练习赛69E-子串【树状数组】

正题 题目链接:https://ac.nowcoder.com/acm/contest/7329/E 题目大意 给出一个nnn的排列&#xff0c;求有多少个区间[l,r][l,r][l,r]使得最大值是rrr&#xff0c;最小值是lll。 解题思路 首先对于一个位置的值作为左端点和右端点都有一段合法区间&#xff08;到左边第一个比…

[译]如何在.NET Core中使用System.Drawing?

你大概知道System.Drawing&#xff0c;它是一个执行图形相关任务的流行的API&#xff0c;同时它也不属于.NET Core的一部分。最初是把.NET Core作为云端框架设计的&#xff0c;它不包含非云端相关API。另一方面&#xff0c;.NET Core是跨平台框架&#xff0c;它不包含任何操作系…

【dfs】棋盘变幻

棋盘变幻 题目大意&#xff1a; 有一些棋子&#xff08;黑/白&#xff09;&#xff0c;可以将某一列的棋子颜色反转&#xff0c;要黑棋尽可能小 原题&#xff1a; 题目描述 小G在一个n*m的棋盘上随意放上了一些黑色的棋子&#xff0c;然后又在剩下所有没有放棋子的格子里放…