这是一套去年在长沙考过的题,但是我当时就没理清楚+没写题解(我以前很多博客都写得跟shi一样,完全没有意义,看到就想打当时的我),所以又考得稀烂。

T1.star way to heaven

容易想到二分+并查集,二分距离所有星星和边界的最小距离r,也就是距离这些点r以内的范围不能走,也就是看以每个点为圆心r为半径的圆能不能把上下都堵满。

这个做法会被卡成80分。正解是用最小生成树代替二分的过程。答案一定是两个点间的距离,最小生成树相当于是从小到大的枚举答案,可以满足当连接一条边权为w的边时,距离小于w的点都联通了,最后答案就是从上边界走到下边界的树上路径上的最大边权(去掉这条边就能不连通啦)。我写成了整颗树上的最大边权然后爆0了。

 //Achen
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=;
using namespace std;
typedef long long LL;
typedef double db;
int n,m,k;
db ans; template<typename T>void read(T &x) {
char ch=getchar(); T f=; x=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} struct node {
int x,y;
}p[N]; LL pf(LL x) { return x*x; } LL get_dis(int a,int b) {
if(a>b) swap(a,b);
if(a<=n&&b<=n) return pf(p[a].x-p[b].x)+pf(p[a].y-p[b].y);
else if(a<=n&&b==n+) return pf(m-p[a].y);
else if(a<=n&&b==n+) return pf(p[a].y);
else if(a==n+&&b==n+) pf(m);
} int ecnt,fir[N],nxt[N<<],to[N<<];
LL val[N<<];
void add(int u,int v,LL w) {
nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
} LL dfs(int x,int fa,LL mx) {
if(x==n+) return mx;
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {
LL tp=dfs(to[i],x,max(mx,val[i]));
if(tp!=) return tp;
}
return ;
} LL dis[N];
int pr[N];
int vis[N];
void prim() {
memset(dis,/,sizeof(dis));
dis[n+]=;
For(i,,n+) {
int kk=;
For(j,,n+) if(!vis[j]) {
if(!kk||dis[j]<dis[kk]) kk=j;
}
add(pr[kk],kk,dis[kk]);
dis[kk]=;
vis[kk]=;
For(j,,n+) if(!vis[j]) {
LL d=get_dis(j,kk);
if(dis[kk]+d<dis[j]) {
pr[j]=kk;
dis[j]=dis[kk]+d;
}
}
}
} #define ANS
int main() {
#ifdef ANS
freopen("starway.in","r",stdin);
freopen("starway.out","w",stdout);
#endif
read(n); read(m); read(k);
n=k;
For(i,,k) {
read(p[i].x);
read(p[i].y);
}
prim();
ans=dfs(n+,,);
ans=sqrt(ans)/2.0;
printf("%.8lf\n",ans);
Formylove;
}

T2.God knows

这题好神啊。当年我在长沙看了一天才看懂(大概只是当时以为懂?), 然后现在根本不知道我当时在想/写些啥子。。

一句话题解就是,线段树维护单调栈优化dp。

把p[i]看成高度,删除一个点就是删掉所有它前面比它高的和它后面比他矮的,那么删除的一定是一个高度单增的序列,且满足不在序列里的数一定存在它前面高度比它高或者它后面高度比它矮的数在序列中,也就是说这是一个极长上升序列。f[i]表示选以i结尾的极长上升序列的答案,f[i]就是通过i之前的一个高度小于i的j,且j是j~i中比i矮的中最高的一个,这样的j来更新i,这样的j所在的是一个由i之前的比i矮的数组成的单调降的单调队列。

考虑如何维护这个单调队列?保证在i之前只要按i从小到大扫就好,要比i矮可以用线段树维护(一开始是标号从小到大对应高度从大到小的单调队列,现在线段树上高度从小到大,那么对应的就是一个标号从大到小的单调队列),那么现在只要在线段树一个区间内维护单降队列就ok了。

线段树如何维护单调队列,参考楼房重建一题。还是解释一下代码以免以后看来想打自己,按高度建线段树,线段树上每个节点维护s[x],sl[x]两个pr,s[x]表示以当前区间做单调队列,(队列中的最大值,队列中的数的最小f值),sl[x]表示当前区间的左子区间在合并右子区间(合并后左边队列会在队尾上弹一些元素对吧)后的s的情况,用一个函数calc(l,r,x)表示l,r的区间做单调队列,最后入队的元素是x时队列的情况,这样就可以做了,具体参考代码。

 //Achen
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
#define inf 0x7777777
const int N=2e5+;
using namespace std;
typedef long long LL;
typedef double db;
int n,p[N],c[N],f[N]; template<typename T>void read(T &x) {
char ch=getchar(); T f=; x=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} #define pr pair<int,int>
#define fi first
#define se second
#define lc (x<<1)
#define rc ((x<<1)|1)
#define mid ((l+r)>>1)
#define mp make_pair
pr s[N<<],sl[N<<]; pr operator +(const pr&A,const pr&B) {
if(A.fi==) return B; if(B.fi==) return A;
return mp(max(A.fi,B.fi),min(A.se,B.se));
} void build(int x,int l,int r) {
s[x]=sl[x]=mp(,inf); //A1
if(l==r) return;
build(lc,l,mid); build(rc,mid+,r);
} pr calc(int x,int l,int r,int last) {
if(l==r) { return s[x].fi>last?s[x]:mp(,inf); }
if(s[rc].fi>last) return sl[x]+calc(rc,mid+,r,last);
else return calc(lc,l,mid,last);
} void upd(int x,int l,int r) {
s[x]=s[lc]+s[rc];
sl[x]=calc(lc,l,mid,s[rc].fi);
} void update(int x,int l,int r,int pos,pr t) {
if(l==r) { s[x]=t; return ; }
if(pos<=mid) update(lc,l,mid,pos,t);
else update(rc,mid+,r,pos,t);
upd(x,l,r);
} pr rs; //(0,inf)
void qry(int x,int l,int r,int ql,int qr) {
if(l>=ql&&r<=qr) { rs=rs+calc(x,l,r,rs.fi); return; }
if(qr>mid) qry(rc,mid+,r,ql,qr);
if(ql<=mid) qry(lc,l,mid,ql,qr);
} #define ANS
int main() {
#ifdef ANS
freopen("knows.in","r",stdin);
freopen("knows.out","w",stdout);
#endif
read(n);
For(i,,n) read(p[i]);
For(i,,n) read(c[i]);
build(,,n);
For(i,,n) {
rs=mp(,inf);
qry(,,n,,p[i]);
f[i]=rs.fi==?c[i]:rs.se+c[i];
update(,,n,p[i],mp(i,f[i]));
}
rs=mp(,inf);
qry(,,n,,n);
printf("%d\n",rs.se);
Formylove;
}
/*
5
3 1 4 5 2
3 4 3 4 1
*/

T3.Lost my music

代码十分短小优美,用大佬的写题解方式就是:这是一道可持久化栈维护凸包的裸题。

我记得这题是可持久化栈维护凸包,但是并打不来。

题目要求的是一个斜率形式,画到图上就是求前面的点到我的斜率的最小值,

如图,中间的j点无论如何都不优,所以维护的这样一个上凸壳

并且我和我在凸壳上的前一个点的斜率就是我的答案(我考场上竟然写了在凸包上三分,我到底在想些什么???)

凸壳是用单调栈维护的,这个在树上就得搞个可持久化栈了。可持久化栈用倍增实现,f[x][i]表示凸壳上我前面的2^i个点,弹栈的时候就可以倍增地弹,就相当于回溯到那个点所维护的凸壳的状态。

Rep(i,18,0) if(f[tx][i]&&f[f[tx][i]][0]&&dcmp(xl(f[tx][i],x)-xl(f[tx][i],f[f[tx][i]][0])>=0)) {
tx=f[f[tx][i]][0];
}
if(f[tx][0]&&dcmp(xl(tx,x)-xl(tx,f[tx][0])>=0)) tx=f[tx][0];

因为我弹的时候是从我前面的前面开始弹的,相当于没考虑只弹一个的情况,所以要有下面那句等于特判。

 //Achen
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=5e5+;
using namespace std;
typedef long long LL;
typedef double db;
int n,c[N],f[N][];
db ans[N]; template<typename T>void read(T &x) {
char ch=getchar(); T f=; x=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} int ecnt,fir[N],nxt[N<<],to[N<<];
void add(int u,int v) {
nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
} int d[N];
#define eps 1e-10
int dcmp(db x) { return fabs(x)<eps?:(x>?:-); }
db xl(int a,int b) {
return (-c[a]+c[b])/((db)d[a]-d[b]);
} void DFS(int x,int p) {
d[x]=d[p]+;
int tx=p;
Rep(i,,) if(f[tx][i]&&f[f[tx][i]][]&&dcmp(xl(f[tx][i],x)-xl(f[tx][i],f[f[tx][i]][])>=)) {
tx=f[f[tx][i]][];
}
if(f[tx][]&&dcmp(xl(tx,x)-xl(tx,f[tx][])>=)) tx=f[tx][];
f[x][]=tx;
if(x!=) ans[x]=xl(tx,x);
For(i,,) f[x][i]=f[f[x][i-]][i-];
for(int i=fir[x];i;i=nxt[i])
DFS(to[i],x);
} #define ANS
int main() {
#ifdef ANS
freopen("lost.in","r",stdin);
freopen("lost.out","w",stdout);
#endif
read(n);
For(i,,n) read(c[i]);
For(i,,n) {
int fx;
read(fx);
add(fx,i);
}
DFS(,);
For(i,,n) printf("%.10lf\n",ans[i]);
Formylove;
}

NOIp2018集训test-9-17(am)的更多相关文章

  1. NOIp2018集训test-9-16(联考二day2)

    T1旋转子段 一开始脑袋抽了花了近一个小时写了个跟这题毫无关系的莫名其妙的代码,一急代码就各种bug,最后t1就花了一个半小时多,然后后面时间不太够了,考得稀烂. 因为每个数存在唯一的中心使得绕这个中 ...

  2. [2016北京集训测试赛17]crash的游戏-[组合数+斯特林数+拉格朗日插值]

    Description Solution 核心思想是把组合数当成一个奇怪的多项式,然后拉格朗日插值..:哦对了,还要用到第二类斯特林数(就是把若干个球放到若干个盒子)的一个公式: $x^{n}=\su ...

  3. NOIp2018集训test-10-24(am&pm)

    李巨连续AK三场了,我跟南瓜打赌李巨连续AK七场,南瓜赌李巨连续AK五场. DAY1 T1 qu 按题意拿stack,queue和priority_que模拟即可.特判没有元素却要取出的情况. T2 ...

  4. NOIP2018 集训(三)

    A题 Tree 问题描述 给定一颗 \(n\) 个点的树,树边带权,试求一个排列 \(P\) ,使下式的值最大 \[\sum_{i=1}^{n-1} maxflow(P_i, P_{i+1}) \] ...

  5. NOIP2018 集训(二)

    A题 神炎皇 问题描述 神炎皇乌利亚很喜欢数对,他想找到神奇的数对. 对于一个整数对 \((a,b)\) ,若满足 \(a+b\leq n\) 且 \(a+b\) 是 \(ab\) 的因子,则称 为神 ...

  6. NOIP2018 集训(一)

    A题 Simple 时间限制:1000ms | 空间限制:256MB 问题描述 对于给定正整数\(n,m\),我们称正整数\(c\)为好的,当且仅当存在非负整数\(x,y\)使得\(n×x+m×y=c ...

  7. NOIp2018集训test-10-18 (bike day4)

    这是一套简单题,这几天的考试让bike老爷感觉很绝望,说实话我也确实不知道还能怎么更简单了. 这几天的题换做llj.sxy应该都能轻松AK吧,至少随便考个250+应该不是问题吧,我越来越觉得觉得我跟他 ...

  8. NOIp2018集训test-10-17 (bike day3)

    发现自己gradully get moodier and moodier了 负面情绪爆发地越来越频繁,根本out of control,莫名其妙地就像着了魔一样 为什么用英语大概是因为今天早上早自习因 ...

  9. NOIp2018集训test-10-16 (bike day2)

    “毕姥爷:今天的题好简单啊,你们怎么考得这么烂啊,如果是noip你们就凉透了啊“ 今天的题难度应该是3.2.1递减的,但是我不知道哪根筋没搭对,平时我最多1h多就弃题了,今天硬生生写了2h20min的 ...

  10. [雅礼NOIP2018集训] day6

    打满暴力好像是一种挑战,已经连续几天考试最后一个小时自闭了,因为自以为打完了暴力,然而,结果往往差强人意 大概是考试的策略有些问题 T1: 我们设$g[x]$为在x时取小于等于m个物品的最大价值,下面 ...

随机推荐

  1. 安卓8.0真机运行appium1.4遇到的问题:运行自动化脚本,手机自动安装 settings.apk和unclock.apk,执行脚本时提示安装UnicodeIME-debug.apk失败,怎么关掉自动安装?

    运行自动化脚本,手机自动安装 settings.apk和unclock.apk,执行脚本时提示安装UnicodeIME-debug.apk失败,怎么关掉自动安装? 这3个apk的目录分别是: D:\P ...

  2. vue 计算属性的setter getter

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. vue项目base64转img

    最近一个vue项目中,有个需求是, 发送消息是base64时,转换成图片预览发送出去. 输入框: <el-input class="input-box" ref=" ...

  4. Java——类的成员之五:内部类

    3.6 类的成员之五:内部类 3.6.1 静态内部类 ①静态内部类可以等同看做静态变量. ②内部类重要的作用:可以访问外部类中私有的数据. ③静态内部类可以直接访问外部类的静态数据,无法直接访问成员. ...

  5. c#开发应避免的几个小滥用

    一 String和StringBuilder              少量的字符串操作不宜采用StringBuilder.      由于string是不可变得对象,对于string的叠加,每次操作 ...

  6. 深入浅出 Vue.js 第九章 解析器---学习笔记

    本文结合 Vue 源码进行学习 学习时,根据 github 上 Vue 项目的 package.json 文件,可知版本为 2.6.10 解析器 一.解析器的作用 解析器的作用就是将模版解析成 AST ...

  7. JCF——Map

    Hashtable LinkedHashMap Properties

  8. error C2872: “ACCESS_MASK”: 不明确的符号

    原因:opencv3.0或者3.1的using namespace cv和windows.h中ACCESS_MASK定义冲突. 解决方案:注释掉所有的using namespace cv,然后在需要的 ...

  9. undefined reference to `mysql_init'解决办法

    命令行后面加入 -l mysqlclient 例如: 对mysqlQuery.c编译,使用gcc mysqlQuery.c -o mysqlQuery -l mysqlclient,即可编译成功.

  10. 贪婪算法--Python

    贪婪算法:每步都采取最优的做法,即每步都选择局部最优解,最终得到的就是全局最优解. 假设你办了个广播节目,要让全美50个州的听众都收听得到.为此你需要决定在哪些广播台播出.在每个广播台播出都需要支付费 ...