《凉宫春日的忧郁》专场

T1

考试的时候连题面都没看懂,都没往图论这方面想,更别提最小生成树。

正解:

最小生成树prim,好像是什么欧几里得生成树,寒假时候的东西了,我直接找的blog看,没看见这么玩意,果然还是太菜了

平面欧几里得最小生成树(EMST)来自wiki百科

直接prim,套板子就好,把上下边界压成一个点,注意,在prim过程中,第一个for循环找出的点如果为压缩后的上边界,此时直接break就好,

prim跟点有关,kruskal跟边有关,此图为完全图,边数达到了 \(n^{2}\),显然用prim更优,用kruskal也可,就是慢很多。

Code
#include<cmath>
#include<cstdio>
#include<iostream>
#define MAX 6010
#define INF 114514810
#define re register
namespace OMA
{
int n,m,k;
bool vis[MAX];
double ans,dis[MAX];
double x[MAX],y[MAX];
inline double Dis(int i,int j)
{ return (i>k||j>k||!i||!j)?sqrt((y[i]-y[j])*(y[i]-y[j])):sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); }
inline void prim()
{
for(re int i=0; i<=k+1; i++)
{ dis[i] = INF; }
dis[0] = 0;
for(re int i=0; i<=k+1; i++)
{
int tmp = 0,top = INF;
for(re int j=0; j<=k+1; j++)
{
if(!vis[j]&&dis[j]<top)
{ tmp = j,top = dis[j]; }
}
if(tmp==k+1)
{ break ; }
vis[tmp] = true;
ans = std::max(ans,dis[tmp]);
for(re int j=0; j<=k+1; j++)
{ dis[j] = std::min(dis[j],Dis(j,tmp)); }
}
}
signed main()
{
scanf("%d %d %d",&n,&m,&k);
for(re int i=1; i<=k; i++)
{ scanf("%lf%lf",&x[i],&y[i]); }
y[k+1] = m,prim();
printf("%0.9lf\n",ans/2);
return 0;
}
}
signed main()
{ return OMA::main(); }

T2

不会dp,所以考试的时候,写的贪心,又写假贪心,改后的贪心没交上,假的骗了10pts,不要脸的说一下假贪心

将左边的点跟右边连起来的点用结构体存起来,按差值排一下序,差值越大,则交线越多,然后就从1开始暴搜,再多开一个二维数组 \(line_{i,j}\),表示此时是以i这条线开始删的,第j条线被删掉了,暴搜下一条线时,转移一下状态,转移答案时,判断是否全删完了,再转移。复杂度,应该是\(O(n^{3})\)

贪心
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAX 10010
#define re register
namespace OMA
{
int n,ans=0x3f3f3f3f;
int c[MAX];
inline int abs(int a)
{ return a>=0?a:-a; }
struct node
{
int l,r,c;
friend inline bool operator <(const node &a,const node &b)
{ return abs(a.l-a.r)>abs(b.l-b.r); }
}p[MAX];
int lr[MAX],rl[MAX];
bool line[MAX][MAX];
inline int read()
{
int s=0,w=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-')w=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ s=s*10+ch-'0'; ch=getchar(); }
return s*w;
}
inline int min(int a,int b)
{ return a<b?a:b; }
inline void dfs(int i,int res,int cast)
{
line[i][p[i].r] = true;
res -= abs(p[i].r-p[i].l)+1;
cast += p[i].c;
if(p[i].l>p[i].r)
{
for(re int j=p[i].r; j<=n; j++)
{ line[i][j] = true; }
}
else
{
for(re int j=1; j<=p[i].r; j++)
{ line[i][j] = true; }
}
bool flag = true;
for(re int j=1; j<=n; j++)
{
if(!line[i][j])
{ flag = false; }
}
if(flag&&res<=0)
{ ans = min(ans,cast); return ; }
for(re int j=1; j<=n; j++)
{
if(!line[i][p[j].r])
{
for(re int k=1; k<=n; k++)
{ line[j][k] = line[i][k]; }
dfs(j,res,cast);
}
}
}
inline void clear()
{ memset(line,0,sizeof(line)); }
signed main()
{
n = read();
for(re int i=1; i<=n; i++)
{ p[i] = (node){i,read()}; }
for(re int i=1; i<=n; i++)
{ p[i].c = read(); }
std::sort(p+1,p+1+n);
for(re int i=1; i<=n/2; i++)
{ dfs(i,n,0),clear(); }
printf("%d\n",ans);
return 0;
}
}
signed main()
{ return OMA::main(); }

正解线段树维护上升序列,咕了。

T3

暴力跳爹50pts。

50pts
#include<cstdio>
#define MAX 500010
#define re register
namespace OMA
{
int n;
struct Graph
{
int next;
int to;
}edge[MAX<<1];
int dep[MAX];
int cnt=1,head[MAX];
int fa[MAX],bin[MAX];
double ans[MAX];
int c[MAX],dis[MAX];
inline int read()
{
int s=0,w=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-')w=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ s=s*10+ch-'0'; ch=getchar(); }
return s*w;
}
inline void add(int u,int v)
{
edge[++cnt].next = head[u];
edge[cnt].to = v;
head[u] = cnt;
}
inline double min(double a,double b)
{ return a<b?a:b; }
inline void dfs(int u,int fat)
{
fa[u] = fat;
int tmp = fa[u];
while(tmp)
{
ans[u] = min(ans[u],1.0*(c[tmp]-c[u])/(1.0*(dis[u]+dis[tmp]-2*dis[tmp])));
tmp = fa[tmp];
}
for(re int i=head[u]; i; i=edge[i].next)
{
int v = edge[i].to;
if(v!=fat)
{
dis[v] = dis[u]+1;
dfs(v,u);
}
}
}
signed main()
{
n = read();
for(re int i=2; i<=n; i++)
{ bin[i] = bin[i>>1]+1; }
for(re int i=1; i<=n; i++)
{ c[i] = read(); }
for(re int v=2; v<=n; v++)
{
ans[v] = 0x3f3f3f3f;
int u = read();
add(u,v),add(v,u);
}
dfs(1,0);
for(re int i=2; i<=n; i++)
{ printf("%0.10lf\n",ans[i]); }
return 0;
}
}
signed main()
{ return OMA::main(); }
/*

正解:

我们先将原式子转换一下

\[\frac{c_{anc}-c_{u}}{dis(u,v)}=\frac{c_{anc}-c_{u}}{dep_{u}-dep_{anc}}=-\frac{c_{u}-c_{anc}}{dep_{u}-dep_{anc}}
\]

然后以c为y轴,dep为x轴,建立坐标系,发现这个式子其实就是在求斜率,那么考虑维护凸包,且只用维护下凸包,上凸包对答案造不成贡献。

暴力弹栈的话,会t成80pts精心构造的数据,所以考虑倍增弹栈

或者说这叫可持久化栈

看了一个早上几何里的凸包

Code
#include<cstdio>
#define MAX 500010
#define re register
namespace OMA
{
int n;
struct Graph
{
int next;
int to;
}edge[MAX<<1];
int cnt=1,head[MAX];
double ans[MAX];
int c[MAX],dep[MAX];
int fa[MAX][30],bin[MAX];
inline int read()
{
int s=0,w=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-')w=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ s=s*10+ch-'0'; ch=getchar(); }
return s*w;
}
inline void add(int u,int v)
{
edge[++cnt].next = head[u];
edge[cnt].to = v;
head[u] = cnt;
}
inline double work(int u,int v)
{ return 1.0*(c[u]-c[v])/(1.0*(dep[v]-dep[u])); }
inline void dfs(int u,int fat)
{
int anc = fat;
dep[u] = dep[fat]+1;
for(re int i=bin[dep[u]]; ~i; i--)
{
if(fa[anc][i]<=1)
{ continue ; }
if(work(fa[fa[anc][i]][0],u)<=work(fa[anc][i],u))
{ anc = fa[anc][i]; }
}
if(anc>1&&work(fa[anc][0],u)<=work(anc,u))
{ anc = fa[anc][0]; }
fa[u][0] = anc;
for(re int i=1; i<=bin[dep[u]]; i++)
{ fa[u][i] = fa[fa[u][i-1]][i-1]; }
for(re int i=head[u]; i; i=edge[i].next)
{
int v = edge[i].to;
if(v!=fat)
{ dfs(v,u); }
}
}
signed main()
{
n = read();
for(re int i=1; i<=n; i++)
{ c[i] = read(); }
for(re int v=2; v<=n; v++)
{
bin[v] = bin[v>>1]+1;
int u = read();
add(u,v),add(v,u);
}
dfs(1,0);
for(re int i=2; i<=n; i++)
{ printf("%0.10lf\n",work(fa[i][0],i)); }
return 0;
}
}
signed main()
{ return OMA::main(); }

noip16的更多相关文章

  1. [Luogu 1850] noip16 换教室

    [Luogu 1850] noip16 换教室 好久没有更博客了,先唠嗑一会,花了两天的空闲时间大致做完了昨年的noip真题 虽然在经过思考大部分题目都可出解(天天爱跑步除外),但是并不知道考试时候造 ...

  2. 【NOIP16提高组】换教室

    [题目链接] 点击打开链接 [算法] 概率DP 先跑一遍floyed,求出每个教室之间的最短路径,存在数组dist[][]中,时间复杂度O(V^3) 设计状态,f[i][j][k]表示当前选到第i个教 ...

  3. 20210715 noip16

    考场 乍一看 T1 像是二分答案,手玩样例发现可以 \(O(k^2)\) 枚举点对,贪心地更新答案,完了?有点不信,先跳了 T2 的形式有点像逆序对,但没啥想法 T3 的式子完全不知道如何处理,一看就 ...

  4. 20210716考试-NOIP16

    考场时Prim的 $i$ 写成 $k$ 100->0 rank1->rank23 T1 Star Way To Heaven 考场正解:假设你要二分答案,则几个圆组成几道"屏障& ...

随机推荐

  1. XCTF Normal_RSA

    这题本来算是很常规的rsa了,下载附件 发现有个公钥文件,还有一个加密文件,这种题之前有遇到一次,做法和这个类似,上次那个是用rsa的库,直接解的,这次直接用常规的,好像更简单,记录下模板 记事本打开 ...

  2. coretext简单使用

    相对于UIKit,使用coretext绘制文本效率高,具有更高的自由度,可随时插入图片,增加文本点击事件等. 1.增加文本的点击事件 思路:定义UILabel子类,设置可点击的富文本range及其他属 ...

  3. gitlab用户,组,项目权限管控

    前言:gitlab上的权限管控是非常重要的,尤其是很多研发人员开发一个项目.这个是我总结的权限管控. 1.这个是创建项目时开放权限设置   2.这个创建用户设置的权限   3.用户权限,5种类型用户是 ...

  4. 干掉 Postman?测试接口直接生成API文档,这个工具贼好用

    大家好,我是小富~ 前几天粉丝群有小伙伴问,有啥好用的API文档工具推荐,无意间发现了一款工具,这里马不停蹄的来给大家分享一下. ShowDoc一个非常适合团队的在线API文档工具,也支持用docke ...

  5. viewport深入理解和使用

    什么是viewport ? viewport是用户网页的可视区域,也可叫做视区.手机浏览器是把页面放在一个虚拟的窗口(viewport)中,通常这个虚拟的窗口比屏幕宽,这样就不用把网页挤到很小的窗口中 ...

  6. Command 'ifconfig' not found, but can be installed with: sudo apt install net-tools VM Ubuntu 解决方案

    VMware下安装的Ubuntu 一开始由于Firefox连不上网,然后通过看了https://www.bbsmax.com/A/VGzlEGYJbq/这个文章之后,自己也测了一下,确实好用 但是if ...

  7. 传统.NET 4.x应用容器化体验(4)

    上一篇我们试着将.NET 4.x的镜像推送到harbor私有镜像仓库,本篇我们来使用一下阿里云的镜像仓库服务并了解一下携程的实践. 1 关于阿里云镜像仓库 阿里云容器镜像服务(简称 ACR)是面向容器 ...

  8. Spring总结之SpringMvc上

    一.简介 Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架. 二.流程架构 1.用户发送请求至 前端控制器DispatcherServlet ...

  9. HDFS学习总结之API交互

    第一种.shell交互 官方文档:http://archive.cloudera.com/cdh5/cdh/5/hadoop-2.6.0-cdh5.7.0/hadoop-project-dist/ha ...

  10. oracle 密码详解以及破解

    参考的相关资料等: https://docs.oracle.com/en/database/oracle/oracle-database/18/spmsu/finding-and-resetting- ...