《凉宫春日的忧郁》专场

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. Jmeter监控服务器CPU,Memory,Disk,Network性能指标

    本文主要说一下如何通过JMeter插件来监控服务器CPU.内存.磁盘.网络等相关资源. 一.下载 第一种方案: 首先进入网址https://jmeter-plugins.org/downloads/o ...

  2. Java基础00-接口组成更新31

    1. 接口组成更新 1.1 接口组成更新概述 1.2 接口中默认方法 代码示例: 需求: 1:定义一个接口MyInterface,里面有两个抽象方法: void show1(); void show2 ...

  3. 痞子衡嵌入式:嵌入式Cortex-M裸机环境下临界区保护的三种实现

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是Cortex-M裸机环境下临界区保护的三种实现. 搞嵌入式玩过 RTOS 的朋友想必都对 OS_ENTER_CRITICAL().OS_ ...

  4. 记一次jenkins svn构建过程

    本文主要参考:maven实战第11章Hudson持续集成 安装Hudson,Hudson插件下载不了,尝试结果未果,转而使用Jenkins 放入tomcat的webapp目录,在bin下点击start ...

  5. Java 正则表达式 简单用法

    正则表达式的具体写法网上有很多了,这里只记录在 Java 中怎么使用. java.util.regex.Matcher.java.util.regex.Pattern 主要有: String.matc ...

  6. WCF简单Demo

    WCF,光看书的原理,稍微有点枯燥,通过自己动手,会更容易理解契约声明,面向服务,分布式等概念. 1.创建WCF服务. 2.WcfService1.CS中声明新的契约. namespace WcfSe ...

  7. 从事IT行业 vs 玩卡牌手游

    我曾经玩过一款手游,它一直不停地推出新的更高品质的道具和人物,新出的东西比旧的东西拥有更强力的功能,要想保持领先就必须一直充钱出新东西才行.不管你以前充了十几万还是几十万,如果有半年不充,那就会被新区 ...

  8. 记录21.07.26 —— Vue/cil

    VUE搭载脚手架 搭载环境 下载node node.js下载地址 控制台输入 npm install -g @vue/cil 查看版本 创建vue项目 创建完后会显示启动服务的指令 这个指令可以在pa ...

  9. Mongodb集成LDAP授权

    一.环境简介 Mongodb enterprise v4.0.16 OpenLDAP v2.4.44 二.Mongodb集成LDAP的授权过程 客户端指定某种外部验证方式链接Mongodb: Mong ...

  10. flight.Archives001 / CSS Selectors选择器

    Title/CSS选择器 序 : 这是flight.Archives 梦开始的地方, 作者我熬夜肝出来了这篇文章... 保证这是最简洁高效的 CSS Selectors 教程 Note : 暂时没有能 ...