CF1092 D & E —— 思路+单调栈,树的直径
题目:https://codeforces.com/contest/1092/problem/D1
https://codeforces.com/contest/1092/problem/D2
https://codeforces.com/contest/1092/problem/E
很有趣的题;
对于D1,首先发现两种砖的放法和高度的奇偶性有关(!);
而竖着放的砖不改变一列的奇偶性,也就是确定一列的奇偶性后,它的高度是可以任意的,那么我们就不用考虑实际高度的问题了;
然后发现,如果两列奇偶性相同的列相邻了,那么它们就“无敌”了,可以变成任意高度;
而两列可以合并,只能是它们相邻且奇偶性相同;
这就很像两组括号序列啊!奇数是 (),偶数是 [],那么整个序列就是 (, ), [, ] 相间的;
只要栈顶能完成一个匹配,就弹栈表示这两列“无敌”了;
所以最后要是栈里没有元素或只剩下一个元素,序列就是合法的,否则不合法;
这么简单就做完了!
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int const xn=2e5+;
int n,sta[xn],top;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
int main()
{
n=rd();
for(int i=,x;i<=n;i++)
{
x=rd();
if(top&&(x&)==(sta[top]&))top--;
else sta[++top]=x;
}
if(top<=)puts("YES");
else puts("NO");
return ;
}
D1
对于D2,只能放横着的砖;
那就更简单了,每次先填满最低的一段,如果其长度是奇数就不合法了,否则就和旁边的合并成一段;
这个过程可以用单调栈维护。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int const xn=2e5+;
int n,sta[xn],top,len[xn],a[xn];
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
int main()
{
n=rd();
for(int i=;i<=n;i++)a[i]=rd();
for(int i=,l,j;i<=n;i=j+)
{
j=i; l=;
while(a[i]==a[j+])j++;
while(top&&a[i]>sta[top])
{
if(len[top]&){puts("NO"); return ;}
l=len[top]; top--;
if(top&&sta[top]<a[i])len[top]+=l;
else break;
}
while(top&&sta[top]==a[i])l+=len[top--];
sta[++top]=a[i]; len[top]=l+(j-i+);
//printf("sta[%d]=%d len=%d\n",top,sta[top],len[top]);
}
int l=;
while(top>)
{
l+=len[top--];
if(l&){puts("NO"); return ;}
}
puts("YES");
return ;
}
D2
E题要最小化连通块合成的树的直径,还要输出连边方案;
结论就是找到所有连通块(小树)的直径中点,最大的直径的中点连接所有其他中点;
想想果然很有道理,因为这样其实最终的直径还是最大连通块的直径,除非有几个连通块一样都是最大;
而其他连法都可能让直径更大;
所以只需要找直径中点即可,看了看提交记录,发现可以写得很优美,就是 dfs 同时找直径端点、长度和中点;
因为如果从一端 dfs 到另一端,那么中点一定在路径上,返回的时候记录一下即可;
然后注意特别判断有两个或三个一样大的最大连通块;
直径的性质要好好利用。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define pb push_back
using namespace std;
int const xn=;
int n,hd[xn],ct,to[xn<<],nxt[xn<<],dis[xn],mx,d;
int vis[xn];
struct N{
int x,d;
N(int x=,int d=):x(x),d(d) {}
bool operator < (const N &y) const
{return d<y.d;}
};
vector<N>v;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
void add(int x,int y){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct;}
void dfs(int x)
{
vis[x]=;
if(dis[x]>mx)mx=dis[x],d=x;
for(int i=hd[x],u;i;i=nxt[i])
if(vis[u=to[i]]!=)dis[u]=dis[x]+,dfs(u);
}
bool dfsx(int x)
{
vis[x]=; bool ret=;
if(dis[x]>mx)mx=dis[x],ret=;
for(int i=hd[x],u;i;i=nxt[i])
if(vis[u=to[i]]!=)
{
dis[u]=dis[x]+;
if(dfsx(u))ret=;
}
if(ret&&dis[x]==mx/)d=x;//
return ret;
}
int main()
{
n=rd(); int m=rd(); int ans=;
for(int i=,x,y;i<=m;i++)x=rd(),y=rd(),add(x,y),add(y,x);
for(int i=;i<=n;i++)
if(!vis[i])
{
dis[i]=; mx=-; dfs(i);
dis[d]=; mx=-; dfsx(d);
ans=max(ans,mx); v.pb(N(d,mx));
}
sort(v.begin(),v.end()); int siz=v.size();
if(siz>)
{
ans=max(ans,(v[siz-].d+)/+(v[siz-].d+)/+);//
if(siz>)ans=max(ans,(v[siz-].d+)/+(v[siz-].d+)/+);//
}
printf("%d\n",ans);
int u=v[siz-].x;
for(int i=;i<siz-;i++)
printf("%d %d\n",u,v[i].x);
return ;
}
E
CF1092 D & E —— 思路+单调栈,树的直径的更多相关文章
- 牛客小白月赛13-H(单调栈+树状数组)
题目链接:https://ac.nowcoder.com/acm/contest/549/H 题意:给一个柱状图,包括每个矩阵的宽度和高度,求能组成的最大矩阵的面积. 思路:显然最大矩阵的高一定为n个 ...
- bzoj 4826: [Hnoi2017]影魔【单调栈+树状数组+扫描线】
参考:https://www.cnblogs.com/lcf-2000/p/6789680.html 这是一个相对码量少的做法,用到了区间修改区间查询的树状数组,详见:www.cnblogs.com/ ...
- CodeForces 548D 单调栈
Mike and Feet Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Subm ...
- ☆ [POJ2559] Largest Rectangle in a Histogram 「单调栈」
类型:单调栈 传送门:>Here< 题意:给出若干宽度相同的矩形的高度(条形统计图),求最大子矩形面积 解题思路 单调栈的经典题 显然,最终的子矩形高度一定和某一个矩形相等(反证).因此一 ...
- 【BZOJ4826】【HNOI2017】影魔(扫描线,单调栈)
[BZOJ4826][HNOI2017]影魔(扫描线,单调栈) 题面 BZOJ 洛谷 Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他 ...
- [POJ2559&POJ3494] Largest Rectangle in a Histogram&Largest Submatrix of All 1’s 「单调栈」
Largest Rectangle in a Histogram http://poj.org/problem?id=2559 题意:给出若干宽度相同的矩形的高度(条形统计图),求最大子矩形面积 解题 ...
- 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分
树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...
- poj2631 求树的直径裸题
题目链接:http://poj.org/problem?id=2631 题意:给出一棵树的两边结点以及权重,就这条路上的最长路. 思路:求实求树的直径. 这里给出树的直径的证明: 主要是利用了反证法: ...
- hdu 2196 Computer 树的直径
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...
随机推荐
- EasyDSS流媒体服务器灵活地帮助用户实现摄像机RTSP转RTMP直播功能
简要描述 今天突然接到国内某上市公司同事打来的技术咨询电话,经过简单的沟通,大概所描述的需求是: 1.目前现场有非常多的摄像机资源需要接入: 2.需要将摄像机的RTSP流转成RTMP流接入到微信小程序 ...
- python高级语法进阶
python中几个比较难懂概念进阶. 迭代器 实现了迭代器协议的容器对象,基于如下两个方法: __next__:返回容器的下一个元素 __iter__:返回迭代器本身 由此可见,如果要自定义一个迭代器 ...
- java.util包下面的类---------01---示意图
一直在使用util包下面的这些类,甚至有些没用过的,想要都去认识认识他们!也许在未来的一天可以用到! 图太大不好截图!部分没有截全!
- CSS 布局实例系列(二)如何通过 CSS 实现一个左边固定宽度、右边自适应的两列布局
最近在百度 IFE 训练营中看见的一道题目: 用两种不同的方法来实现一个两列布局,其中左侧部分宽度固定.右侧部分宽度随浏览器宽度的变化而自适应变化 个人总结出如下三种实现思路: 通过绝对定位实现 S ...
- Android系统移植与调试之------->MTK 标准编译命令
命令格式:./maketek [option] [project] [action] [modules]Option: -t ,-tee :输出log信息到当前终端 -o , -opt=-- ...
- centos7 mysql允许远程连接设置
Mysql为了安全性,在默认情况下用户只允许在本地登录,可是在有此情况下,还是需要使用用户进行远程连接,因此为了使其可以远程需要进行如下操作: 一.允许root用户在任何地方进行远程登录,并具有所有库 ...
- 11.2.3 Redis的启动停止
11.2.3 Redis的启动停止 Redis安装配置完成后,启动过程非常简单,执行命令/usr/local/redis/bin/redis-server /usr/local/redis/etc/ ...
- Html标签使用——文字、列表、表格、超链接
注:文章来源于传智播客毕向东老师使用课件和网络.整理学习如下: 一.Html内容 1. Html就是超文本标记语言的简写,是最基础的网页语言. 2. Html是通过标签来定义的语言,代码都是由 ...
- 【leetcode刷题笔记】Same Tree
Given two binary trees, write a function to check if they are equal or not. Two binary trees are con ...
- 【四】MongoDB索引管理
一.索引介绍 在mongodb中,索引用来支持高效查询.如果没有索引,mongodb必须在整个集合中扫描每个文档来查找匹配的文档.但是如果建立合适的索引,mongodb就可以通过索引来限制检查的文档数 ...