noip模拟测试16
这次考试,难度还是不小的,先说一下考试过程,首先看一遍题,觉得开题顺序1 3 2,
然后我就先打了第一题,我当时可能是受到之前做题的限制了,觉得他只能每次走一
格,也就是一个单位长度,但是实际上,他甚至可以走一个曲线,因为题面并没有规定
必须走直线,或者必须走一个单位长度。我当时打了一个dfs,虽然没看懂题面,但还是
得到了10分。用了大概一个小时。然后是T3,暴力思路很简单,就是枚举每个点,然后
一直往上跳到根节点,输出最大值即可。最后是T2,我觉得这是个DP,但是我当时无法
保证正确性,因为应该是求最长的单调上升的序列,没什么思路,我就打了个dfs,
总体来说,这次是暴力分基本上打满了,这次考试的几道题我觉得都非常棒,可以很
好的拓展思路,还可以学到一些常见套路。
题解
T1
这道题思路真是......难以形容,假设我们把所有点连起来,再把上下边界分别看成一个
点,那么我们就可以得到一条线,我们到终点的路径必定会经过这条线上的一条,那么
我们要求得是最小的最大值,就可以利用最小生成树,最后输出最大的边的长度除以2即可
#include<bits/stdc++.h>
#define re register int
#define lc rt<<1
#define rc rt<<1|1
#define mid ((l+r)>>1)
using namespace std;
const int N=6100;
struct CUN
{
int x,y;
}use[N];
int n,m,k,cnt;
double maxx;
double d[N];
bool vis[N];
inline int read()
{
int x=0;
bool f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch^'-')
f=0;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return f?x:(-x);
}
inline double gett(int x,int y)
{
return (double)sqrt((((double)(use[x].x-use[y].x)*(use[x].x-use[y].x))+((double)(use[x].y-use[y].y)*(use[x].y-use[y].y))));
}
inline void pm()
{
cnt=k+1;
for(re i=1;i<cnt;i++)
d[i]=(double)use[i].y;
d[cnt]=(double)m;
for(re i=1;i<=cnt;i++)
{
int u=0;
for(re j=1;j<=cnt;j++)
{
if((!vis[j])&&(u==0||d[j]<d[u]))
u=j;
}
vis[u]=1;
maxx=max(maxx,d[u]);
if(u==cnt)
{
printf("%.10lf\n",maxx/2);
return;
}
for(re y=1;y<cnt;y++)
{
if(!vis[y])
d[y]=min(d[y],gett(u,y));
}
d[cnt]=min(d[cnt],(double)m-(double)use[u].y);
}
}
int main()
{
n=read();
m=read();
k=read();
for(re i=1;i<=k;i++)
{
use[i].x=read();
use[i].y=read();
}
pm();
return 0;
}
T2
我觉得这道题应该是最有思维含量的一道题了
首先说一个n^2的dp,(题解说了几句废话,还不如不看....)我们令 f[i] 表示,以 i 为
结尾的最长上升序列的最小权值,显然\(f_i=\min(f_i,f_j+c_j)\) , 但是,为了保证这是一
个极长的序列,我们就要利用一个 last
标记,这个没办法解释的很清楚,具体实
现看代码片段
for(int i=1;i<=n;i++)
s[i]=read();
for(int i=1;i<=n;i++)
val[i]=read();
las=INF;
memset(f,0x3f,sizeof(f));
for(int i=1;i<=n;i++)
if(las>s[i])
{
las=s[i];
f[i]=val[i];
}
for(int i=2;i<=n;i++)
{
int las=0;
for(int j=i-1;j>=1;j--)
if(s[j]<s[i]&&las<s[j])
{
f[i]=min(f[i],f[j]+val[i]);
las=s[j];
}
}
las=0;
for(int i=n;i>=1;i--)
{
if(s[i]<las) continue;
las=s[i];
ans=min(ans,f[i]);
}
printf("%lld",ans);
应该不难理解,好的,接下来我们就看这个线段树优化(我当时理解了好长时间),
大概说一下,线段树下标表示对岸的位置,权值存的是以对面那个点为结尾的极长上
升序列的dp值,mx表示当前区间内极长上升序列的最靠右的端点,加上代码注释应
该比较好理解
#include<bits/stdc++.h>
#define re register int
#define lc rt<<1
#define rc rt<<1|1
#define mid ((l+r)>>1)
using namespace std;
const int N=2e5+10;
const int INF=1e9+1;
int n,las,v;
int p[N],c[N],dp[N<<4],vl[N<<4],mx[N<<4];
struct Segment_tree
{
inline int ask(int rt,int l,int r,int la)
{
if(l==r)
return (mx[rt]>la)?dp[rt]:INF;
if(mx[rc]<=la)
return ask(lc,l,mid,la);
return min(vl[rt],ask(rc,mid+1,r,la));
}
inline void insert(int rt,int l,int r,int p,int pos,int w)
{
if(l==r)
{
dp[rt]=w; //dp是当前点的dp值
mx[rt]=pos;// mx 是当前点的最长上升序列的最小权的最右边的端点
return;
}
if(p>mid)
insert(rc,mid+1,r,p,pos,w);
else
insert(lc,l,mid,p,pos,w);
mx[rt]=max(mx[lc],mx[rc]);
vl[rt]=ask(lc,l,mid,mx[rc]); // vl 存储左区间的值
}
inline void query(int rt,int l,int r,int p)
{
if(p>=r)
{
v=min(v,ask(rt,l,r,las));
las=max(las,mx[rt]);//las不停往上跳,相当与 n^2 dp 里的last
return;
}
if(p>mid)
query(rc,mid+1,r,p);
query(lc,l,mid,p);
}
}T;
int main()
{
scanf("%d",&n);
for(re i=1;i<=n;i++)
scanf("%d",&p[i]);
for(re i=1;i<=n;i++)
scanf("%d",&c[i]);
for(re i=1;i<=n;i++)
vl[i]=INF;
for(re i=1;i<=n;i++)
{
las=0;
v=INF;
T.query(1,1,n,p[i]);
T.insert(1,1,n,p[i],i,((v<INF)?v:0)+c[i]);//更新值
}
v=INF,las=0;
T.query(1,1,n,n);
printf("%d\n",v);
return 0;
}
T3
好吧,这种存在上下比值的问题一般可以转化成斜率,就像本题,
\(\dfrac{c_v-c_u}{deep_u-deep_v}\),可以转化为 \(-\dfrac{c_v-c_u}{deep_v-deep_u}\)
这个可以看作斜率的形式,所以我们要求原式的最小值就是求斜率的最大值,这东西可以用一个倍增数组来实现,我们更新答案的同时修改父亲,具体实现见代码
#include<bits/stdc++.h>
#define re register int
#define lc rt<<1
#define rc rt<<1|1
#define mid ((l+r)>>1)
#define re register int
#define ii inline int
#define iv inline void
using namespace std;
const int N=5e5+10;
int t,n,m,tot,timi;
int fa[N],f[N][30],c[N];
int head[N],to[N<<1],next[N<<1],deep[N];
ii read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=0;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return (f)?x:(-x);
}
iv add(int x,int y)
{
to[++tot]=y;
next[tot]=head[x];
head[x]=tot;
}
inline bool pd(int k,int j,int i)
{
return 1ll*(c[i]-c[k])*(deep[i]-deep[j])>=1ll*(c[i]-c[j])*(deep[i]-deep[k]);
}
iv dfs(int st)
{
///cout<<"st="<<st<<endl;
deep[st]=deep[fa[st]]+1;
int x=fa[st],t;
for(re i=22;i>=0;i--)
{
t=f[x][i];
if(t<2)
continue;
if(pd(f[t][0],t,st))
x=t;
}
if(x!=1&&pd(f[x][0],x,st))
x=f[x][0];
f[st][0]=x;
for(re i=1;i<=22;i++)
f[st][i]=f[f[st][i-1]][i-1];
for(re i=head[st];i;i=next[i])
dfs(to[i]);
}
int main()
{
n=read();
for(re i=1;i<=n;i++)
c[i]=read();
for(re i=2;i<=n;i++)
{
fa[i]=read();
add(fa[i],i);
}
dfs(1);
for(re i=2;i<=n;i++)
printf("%.10lf\n",(double)(c[f[i][0]]-c[i])/(double)(deep[i]-deep[f[i][0]]));
return 0;
}
noip模拟测试16的更多相关文章
- 2019.8.10 NOIP模拟测试16 反思总结【基本更新完毕忽视咕咕咕】
一如既往先放代码,我还没开始改… 改完T1滚过来了,先把T1T2的题解写了[颓博客啊] 今天下午就要走了,没想到还有送行的饯别礼,真是欣喜万分[并没有] 早上刚码完前面的总结,带着不怎么有希望的心情开 ...
- 8.10 NOIP模拟测试16 Blue+Weed+Drink
T1 Blue 贪心,每次跳得时候跳能跳到的最远的地方,跳过的就把他设为0,每次二分找到位置,一直跳就行,如果能跳到的位置就是当前位置或比当前位置还小(数组里现在呆着的这一块石头,二分得到的就是当前位 ...
- NOIP模拟测试16「Drink·blue·weed」
话说这次考试 Drink 非常棒的一道卡常练习题,适合练习卡常 真的很棒 前置卡常知识 1.char要比int快 char是最快的 输出putchar,输入getchar 在这个题快了7000豪 2. ...
- 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组
2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...
- 「题解」NOIP模拟测试题解乱写II(36)
毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...
- 2019.8.9 NOIP模拟测试15 反思总结
日常爆炸,考得一次比一次差XD 可能还是被身体拖慢了学习的进度吧,虽然按理来说没有影响.大家听的我也听过,大家学的我也没有缺勤多少次. 那么果然还是能力问题吗……? 虽然不愿意承认,但显然就是这样.对 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色
2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 数据结构学傻的做法: 对每种颜色开动态开点线段树直接维 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)
2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...
- NOIP模拟测试17&18
NOIP模拟测试17&18 17-T1 给定一个序列,选取其中一个闭区间,使得其中每个元素可以在重新排列后成为一个等比数列的子序列,问区间最长是? 特判比值为1的情况,预处理比值2~1000的 ...
随机推荐
- WEB安全新玩法 [5] 防范水平越权之查看他人订单信息
水平越权是指系统中的用户在未经授权的情况下,查看到另一个同级别用户所拥有的资源.水平越权会导致信息泄露,其产生原因是软件业务设计或编码上的缺陷.iFlow 业务安全加固平台可以缓解部分场景下的水平越权 ...
- http强制缓存、协商缓存、指纹ETag详解
目录 实操目录及步骤 缓存分类 强制缓存 对比缓存 指纹 Etag 摘要及加密算法 缓存总结 每个浏览器都有一个自己的缓存区,使用缓存区的数据有诸多好处,减少冗余的数据传输,节省网络传输.减少服务器负 ...
- CosId 1.0.3 发布,通用、灵活、高性能的分布式 ID 生成器
CosId 通用.灵活.高性能的分布式 ID 生成器 介绍 CosId 旨在提供通用.灵活.高性能的分布式系统 ID 生成器. 目前提供了俩大类 ID 生成器:SnowflakeId (单机 TPS ...
- Redmine部署中遇到的问题
Redmine部署文章: 第一篇:Redmine部署 第二篇:Redmine部署中遇到的问题 上一篇文章我写了Redmine怎样部署(点这里直达上一篇文章),这一篇就写一下在Redmine部署中遇到过 ...
- 【NLP学习其三】在学习什么是嵌入之前,你应该了解什么是词语表征
在了解什么是嵌入(embeddings)之前,我们需要先搞清楚一个词语在NLP中是如何被表示的 注:本次不涉及任何具体算法,只是单纯对概念的理解 词汇表征 One-Hot 词汇的表示方法有很多,最有名 ...
- 温故知新,.Net Core遇见Postman(API Development),进阶分布式微服务高效调式
什么是Postman 环境变量(Environments) 全局协议 描述 变量 初始值 当前值 请求协议 request_protocol http http 授权信息 描述 变量 初始值 当前值 ...
- 登录华科校园网,我用Socket
登录华科校园网,我用Socket 导语: 找一个华科学生问一问,学校的网络怎么样?得到的大多数是负面回答.其实不论是从覆盖区域.网络稳定性.还是速度来说,华科做的都还是可以的(24:00断网除外).可 ...
- 最新的.NET 热重载介绍
今天,我们很高兴的向您介绍 Visual Studio 2019 版本 16.11(预览版 1)和 .NET 6 中的 dotnet watch 命令行工具(预览版 4)中的 .NET 热重载体验的可 ...
- RabbitMQ消息可靠性传输
消息的可靠性投递是使用消息中间件不可避免的问题,不管是使用kafka.rocketMQ或者rabbitMQ,那么在RabbitMQ中如何保证消息的可靠性投递呢? 先再看一下RabbitMQ消息传递的流 ...
- HCNA Routing&Switching之动态路由协议RIP
前文我们了解了动态路由的基本概念,以及动态路由和静态路由的区别,优缺点,动态路由的分类,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14995317.html ...