JOISC 2017 自然公园
吐槽
YMD的课件是真的毒,YYB的也很毒。
题目链接
sol
我是一个一个Subtask做的。。。
Subtask 1
\(O(n^2)\)枚举每两个点有没有边即可。
Subtask 2
链的情况的话,我们可以维护一条链\([l,r]\),这个区间和编号没关系,只是表示\(l,r\)是端点。
考虑每次加一个点进来,我们首先可以判一下是\(x...l...r\)还是\(l...r...x\)。
然后判断\(x\)和端点有没有直接的连边,如果有,连上,返回。
否则,二分出路径上最小的点的编号\(t\),然后两端递归做下去。
Subtask 3
树,以\(0\)为根深度\(log\)。
直接把每个点的儿子找出来,然后把子树内的点一一分配即可。
Subtask 4
树,无特殊性质。
和链差不多,但是要把整个集合和连进来的点判断。
有点细节。
Subtask 5
图,无特殊性质。
和树也差不多,只是每次发现当前点相邻的时候要二分出每条与集合相连的边。
由于点度\(\le 7\)所以复杂度是对的。
end
这题花了我\(3h\),果然还是我太菜了。
细节就看\(code\)吧。
\(code\)
#include "park.h"
#define pb push_back
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cstdio>
const int N=1400;
static int A[1400],o[1400];
int n;
inline void debug(){for(int i=0;i<n;++i)printf("%d ",A[i]);puts("");}
inline bool ask(int l,int r,int *A){if(l>r)std::swap(l,r);return Ask(l,r,A);}
inline void answer(int l,int r){if(l>r)std::swap(l,r);Answer(l,r);}
namespace w1
{
void work()
{
for(int i=0;i<n;++i)
{
A[i]=1;
for(int j=i+1;j<n;A[j]=0,++j)
if(A[j]=1,ask(i,j,A))answer(i,j);
A[i]=0;
}
}
}
namespace w2
{
int binary(int p,int q);
int link(int l,int r);
int link(int &l,int &r,int x);
void work();
}
namespace w3
{
std::vector<int>G[N],son[N];
void solve(int u);
void work();
}
namespace w4
{
std::vector<int>nS,G[N],tS;
int pos[N],vis[N],ov[N];
inline void pre(int x){if(x)A[x]=1;else for(int x:nS)A[x]=1;}
inline void del(int x){if(x)A[x]=0;else for(int x:nS)A[x]=0;}
inline void add(int l,int r){G[l].pb(r),G[r].pb(l),answer(l,r);}
inline void Link(int l,int r);
int binary(int p,int q);
void link(int l,int r);
void work();
}
namespace w5
{
std::vector<int>nS,G[N],tS,pos;
int vis[N],ov[N],now;
inline void pre(int x){if(x)A[x]=1;else for(int x:nS)A[x]=1;}
inline void del(int x){if(x)A[x]=0;else for(int x:nS)A[x]=0;}
inline void add(int l,int r){G[l].pb(r),G[r].pb(l),answer(l,r);}
int binary(int p,int q);
void work();
void bfs(int fr,std::vector<int>&pos);
void calc(std::vector<int>&pos,int r);
inline void Link(int r);
void link(int l,int r);
}
void Detect(int T, int _n)
{
n=_n;memset(A,0,n<<2),memset(o,0,n<<2);
if(T==1)return w1::work();
if(T==2)return w2::work();
if(T==3)return w3::work();
if(T==4)return w4::work();
if(T==5)return w5::work();
}
namespace w2
{
int binary(int p,int q)
{
int l=1,r=n-1,ans=r;A[p]=A[q]=1;
while(l<=r)
{
int mid=l+r>>1;
for(int i=0;i<=mid ;++i)if(i!=p&&i!=q&&!o[i])A[i]=0;
for(int i=mid+1;i<n;++i)if(i!=p&&i!=q&&!o[i])A[i]=1;
if(ask(p,q,A))l=mid+1;
else r=mid-1,ans=mid;
}
return ans;
}
int link(int l,int r)
{
for(int i=0;i<n;++i)A[i]=(i==l||i==r);
if(ask(l,r,A))return answer(l,r),o[l]=o[r]=1;
int x=binary(l,r);return link(l,x)+link(x,r);
}
int link(int &l,int &r,int x)
{
int to,tot=0;
if(l==r)to=l;
else
{
for(int i=0;i<n;++i)A[i]=i!=r;
if(ask(x,l,A))to=l;else to=r;
}
if(to==r)return r=x,link(to,x);
return l=x,link(x,to);
}
void work()
{
int l=0,r=0,cnt=o[0]=1;
while(cnt<n)
{
for(int i=1;i<n;++i)
if(!o[i])cnt+=link(l,r,i);
}
}
}
namespace w3
{
void solve(int u)
{
A[u]=1;
for(int x:G[u])
if(A[x]=1,ask(x,u,A))
answer(u,x),son[u].pb(x),A[x]=0,o[x]=1;
else A[x]=0;
for(int i=0;i<n;++i)A[i]=1;
for(int x:G[u])
if(!o[x])
for(int y:son[u])
{
A[y]=0;
if(!ask(x,u,A)){G[y].pb(x);A[y]=1;break;}
A[y]=1;
}
memset(A,0,n<<2);
for(int x:son[u])solve(x);
}
void work()
{
for(int i=1;i<n;++i)G[0].pb(i);
o[0]=1,solve(0);
}
}
namespace w4
{
inline void Link(int l,int r)
{
tS.pb(r);o[r]=1;if(l)return add(l,r);
if(A[0]=1,A[r]=1,ask(0,r,A))return A[0]=0,A[r]=0,add(0,r);
std::queue<int>Q;Q.push(0);memset(vis,0,sizeof vis);
int cnt=-1;vis[0]=1;
while(!Q.empty())
{
int u=pos[++cnt]=Q.front();Q.pop();
for(int x:G[u])if(ov[x]&&!vis[x])Q.push(x),vis[x]=1;
}
int L=1,R=cnt,ans=L;
while(L<=R)
{
int mid=L+R>>1;
for(int i=1;i<=mid;++i)A[pos[i]]=1;
if(ask(0,r,A))R=mid-1,ans=mid;
else L=mid+1;
for(int i=1;i<=mid;++i)A[pos[i]]=0;
}
add(pos[ans],r),A[0]=A[r]=0;
}
int binary(int p,int q)
{
pre(p),pre(q);
int l=1,r=n-1,ans=r;
while(l<=r)
{
int mid=l+r>>1;
for(int i=mid+1;i<n;++i)if(!o[i]&&i!=p&&i!=q)A[i]=1;
if(ask(p,q,A))l=mid+1;else r=mid-1,ans=mid;
for(int i=mid+1;i<n;++i)if(!o[i]&&i!=p&&i!=q)A[i]=0;
}
del(p),del(q);
return ans;
}
void link(int l,int r)
{
pre(l),pre(r);
if(ask(l,r,A))return del(l),del(r),Link(l,r);
del(l),del(r);int x=binary(l,r);
link(l,x),link(x,r);
}
void work()
{
o[0]=ov[0]=1;nS.pb(0);
for(int i=1;i<n;++i)
if(!o[i])
{
tS.clear(),link(0,i),nS.insert(nS.end(),tS.begin(),tS.end());
for(int x:tS)ov[x]=1;
}
}
}
namespace w5
{
int binary(int p,int q)
{
pre(p),pre(q);
int l=1,r=n-1,ans=r;
while(l<=r)
{
int mid=l+r>>1;
for(int i=mid+1;i<n;++i)if(!o[i]&&i!=p&&i!=q)A[i]=1;
if(ask(p,q,A))l=mid+1;else r=mid-1,ans=mid;
for(int i=mid+1;i<n;++i)if(!o[i]&&i!=p&&i!=q)A[i]=0;
}
del(p),del(q);
return ans;
}
void bfs(int fr,std::vector<int>&pos)
{
std::queue<int>Q;Q.push(fr);ov[fr]=0;
while(!Q.empty())
{
int u=Q.front();Q.pop(),pos.pb(u);
for(int x:G[u])if(ov[x])ov[x]=0,Q.push(x);
}
}
void calc(std::vector<int>&pos,int r)
{
for(int x:pos)A[x]=1;A[r]=1;
if(!ask(pos[0],r,A)){for(int x:pos)A[x]=0;A[r]=0;pos.clear();return;}
for(int i=1;i<pos.size();++i)A[pos[i]]=0;
int L=1,R=pos.size()-1,ans=-1;A[r]=A[pos[0]]=1;
std::vector<int>fz,ff;
if(ask(pos[0],r,A))ans=0;
else
while(L<=R)
{
int mid=L+R>>1;
for(int i=1;i<=mid;++i)A[pos[i]]=1;
for(int i=mid+1;i<pos.size();++i)A[pos[i]]=0;
if(!ask(pos[0],r,A))L=mid+1;else R=mid-1,ans=mid;
for(int i=1;i<=mid;++i)A[pos[i]]=0;
}
A[pos[0]]=A[r]=0;if(ans==-1)return pos.clear();
tS.pb(pos[ans]),add(pos[ans],r);
for(std::vector<int>::iterator it=nS.begin();it!=nS.end();++it)
if(*it==pos[ans]){nS.erase(it);break;}
for(std::vector<int>::iterator it=pos.begin();it!=pos.end();++it)
if(*it==pos[ans]){pos.erase(it);break;}
for(int x:pos)ov[x]=1;
while(pos.size())
{
bfs(pos[0],fz);ff=fz;std::sort(ff.begin(),ff.end());
for(std::vector<int>::iterator it=pos.begin();it!=pos.end();)
if(*(std::lower_bound(ff.begin(),ff.end(),*it))==*it)
it=pos.erase(it);
else ++it;
calc(fz,r);
}
}
inline void Link(int r)
{
std::queue<int>Q;Q.push(0);memset(vis,0,sizeof vis);
int cnt=-1;vis[0]=1;pos.resize(nS.size()),ov[0]=0;
while(!Q.empty())
{
int u=pos[++cnt]=Q.front();Q.pop();
for(int x:G[u])if(!vis[x])Q.push(x),vis[x]=1;
}
calc(pos,r);
}
void link(int l,int r)
{
pre(l),pre(r);
if(ask(l,r,A))
{
del(l),del(r),tS.pb(r);o[r]=1;Link(r);
nS.insert(nS.end(),tS.begin(),tS.end());
tS.clear();return;
}
del(l),del(r);int x=binary(l,r);
link(l,x),link(x,r);
}
void work()
{
o[0]=ov[0]=1;nS.pb(0);
for(int i=1;i<n;++i)
if(!o[i])link(0,i);
}
}
JOISC 2017 自然公园的更多相关文章
- JOISC 2017 Day1 T3 烟花棒
JOISC 2017 Day1 T3 烟花棒 题意: 数轴上有\(N\)人在放烟花,一开始只有第\(K\)个人的烟花是点燃的,烟花燃烧的时间为\(T\)秒,求让所有人的烟花都可以点燃的速度的最小值 ...
- JOISC 2017
Day1 「JOISC 2017 Day 1」开荒者 首先观察部分分发现分档很多,于是考虑一步步思考上来. 首先有一点关键观察(一): 风吹的顺序是无所谓的,令分别往东.西.南.北吹了 \(r, l, ...
- [NOIp 2017]逛公园
Description 策策同学特别喜欢逛公园.公园可以看成一张$N$个点$M$条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,$N$号点是公园的出口,每条边有一个非负权值, 代表策策经 ...
- NOIP 2017 逛公园 记忆化搜索 最短路 好题
题目描述: 策策同学特别喜欢逛公园.公园可以看成一张N个点MM条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. ...
- 「JOISC 2017 Day 3」幽深府邸
题解: 和hnoi2018day2t1基本一样 我想了半小时想出了一个很麻烦的做法 写了之后发现假掉了 刚开始想的是 先预处理出每个门要打开至少要在左边的哪个点$L[]$,右边的哪个点$R[]$ 对每 ...
- NOIP 2017 逛公园 - 动态规划 - 最短路
题目传送门 传送门 题目大意 给定一个$n$个点$m$条边的带权有向图,问从$1$到$n$的距离不超过最短路长度$K$的路径数. 跑一遍最短路. 一个点拆$K + 1$个点,变成一个DAG上路径计数问 ...
- loj2395 [JOISC 2017 Day 2]火车旅行
传送门 分析 我们知道无论往左走还是往右走一定都是往不低于这个点的地方走 于是我们可以考虑用倍增来维护一个点向左和向右走$2^i$最远分别能走到哪里 我们可以先用单调栈求出直走一步的情况,之后再处理倍 ...
- 洛谷 P3953 [ NOIP 2017 ] 逛公园 —— 最短路DP
题目:https://www.luogu.org/problemnew/show/P3953 主要是看题解...还是觉得好难想啊... dfs DP,剩余容量的损耗是边权减去两点最短路差值...表示对 ...
- NOIP 2017 逛公园 题解
题面 这道题是一道不错的计数类DP: 首先我们一定要跑一遍dijkstra来求得每个点到1号点的最短路: 注意题干,题中并没有说所有点都可以到达n好点,只说了存在一条1号点到n号点的路径:所以我们在反 ...
随机推荐
- 11.10 (下午)开课二个月零六天(ajax验证用户名,ajax调数据库)
用ajax验证用户名是否可用 testuid.php <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&quo ...
- 【JVM.3】虚拟机性能监控与故障处理工具
一.概述 经过前面两章对于虚拟机内存分配与回收技术各方面的介绍,相信读者已经建立了一套比较完整的理论基础.理论总是作为指导实践的工具,能把这些执行应用到实际工作中才是我们的最终目的.接下来我们会从实践 ...
- item 1:理解template类型的推导
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 一些用户对复杂的系统会忽略它怎么工作,怎么设计的,但是很高兴去知道它完成的一些事.通过这 ...
- ABP module-zero +AdminLTE+Bootstrap Table+jQuery权限管理系统第十五节--缓存小结与ABP框架项目中 Redis Cache的实现
返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期 缓存 为什么要用缓存 为什么要用缓存呢,说缓存之前先说使用缓存的优点. 减少寄宿服务器的往返调用(round-tr ...
- Slurm任务调度系统部署和测试(源码)(1)
1. 概述1.1 节点信息2. 节点准备3. 部署NTP服务器4. 部署LDAP服务器5. 部署Munge认证服务6. 部署Mysql数据库服务7. 部署slurm7.1 创建slurm用户7.2 挂 ...
- MariaDB 安装与启动 过程记录
1. 安装之前的准备工作 rpm -qa |grep mysql rpm -qa |grep mariadb 按照查出来的软件包使用 yum remove 全部卸载,当然也可以 yum remov ...
- Linux下绑定网卡的操作记录
公司采购的服务器安装了双网卡,并进行bond网卡绑定设置,网卡绑定mode共有七种(0~6) bond0.bond1.bond2.bond3.bond4.bond5.bond6. 第一种模式:mod= ...
- Oracle数据库冷备份与热备份操作梳理
Oracle数据库的备份方式有冷备份和热备份两种,针对这两种备份的实施过程记录如下: 一.Oracle冷备份 概念数据库在关闭状态下完成所有物理系统文件拷贝的过程,也称脱机备份.适合于非归档模式(即n ...
- Linux下"负载均衡+高可用"集群的考虑点 以及 高可用方案说明(Keepalive/Heartbeat)
当下Linux运维技术越来越受到企业的关注和追捧, 在某些企业, 尤其是牵涉到电子商务和电子广告类的网站,通常会要求作负载均衡和高可用的Linux集群方案.那么如何实施Llinux集群架构,才能既有效 ...
- 《Linux内核分析》实践3
<Linux>实践--程序破解 一.掌握NOP.JNE.JE.JMP.CMP汇编指令的机器码 NOP:NOP指令即"空指令".执行到NOP指令时,CPU什么也不做,仅仅 ...