吐槽

YMD的课件是真的毒,YYB的也很毒。

题目链接

LOJ

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 自然公园的更多相关文章

  1. JOISC 2017 Day1 T3 烟花棒

    JOISC 2017 Day1 T3 烟花棒 题意: ​ 数轴上有\(N\)人在放烟花,一开始只有第\(K\)个人的烟花是点燃的,烟花燃烧的时间为\(T\)秒,求让所有人的烟花都可以点燃的速度的最小值 ...

  2. JOISC 2017

    Day1 「JOISC 2017 Day 1」开荒者 首先观察部分分发现分档很多,于是考虑一步步思考上来. 首先有一点关键观察(一): 风吹的顺序是无所谓的,令分别往东.西.南.北吹了 \(r, l, ...

  3. [NOIp 2017]逛公园

    Description 策策同学特别喜欢逛公园.公园可以看成一张$N$个点$M$条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,$N$号点是公园的出口,每条边有一个非负权值, 代表策策经 ...

  4. NOIP 2017 逛公园 记忆化搜索 最短路 好题

    题目描述: 策策同学特别喜欢逛公园.公园可以看成一张N个点MM条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. ...

  5. 「JOISC 2017 Day 3」幽深府邸

    题解: 和hnoi2018day2t1基本一样 我想了半小时想出了一个很麻烦的做法 写了之后发现假掉了 刚开始想的是 先预处理出每个门要打开至少要在左边的哪个点$L[]$,右边的哪个点$R[]$ 对每 ...

  6. NOIP 2017 逛公园 - 动态规划 - 最短路

    题目传送门 传送门 题目大意 给定一个$n$个点$m$条边的带权有向图,问从$1$到$n$的距离不超过最短路长度$K$的路径数. 跑一遍最短路. 一个点拆$K + 1$个点,变成一个DAG上路径计数问 ...

  7. loj2395 [JOISC 2017 Day 2]火车旅行

    传送门 分析 我们知道无论往左走还是往右走一定都是往不低于这个点的地方走 于是我们可以考虑用倍增来维护一个点向左和向右走$2^i$最远分别能走到哪里 我们可以先用单调栈求出直走一步的情况,之后再处理倍 ...

  8. 洛谷 P3953 [ NOIP 2017 ] 逛公园 —— 最短路DP

    题目:https://www.luogu.org/problemnew/show/P3953 主要是看题解...还是觉得好难想啊... dfs DP,剩余容量的损耗是边权减去两点最短路差值...表示对 ...

  9. NOIP 2017 逛公园 题解

    题面 这道题是一道不错的计数类DP: 首先我们一定要跑一遍dijkstra来求得每个点到1号点的最短路: 注意题干,题中并没有说所有点都可以到达n好点,只说了存在一条1号点到n号点的路径:所以我们在反 ...

随机推荐

  1. 开发手记:Linux下更改Oracle表空间大小

    问题:同事反馈我们的测试环境数据库执行SQL和编译PKG非常慢,猜测可能是我们的测试环境数据库的表空间满了,但是我不知道数据库DBA的用户和密码. 步骤1:查看表空间占用情况 SELECT UPPER ...

  2. Nowcoder 牛客练习赛23

    Preface 终于知道YKH他们为什么那么喜欢打牛客网了原来可以抽衣服 那天晚上有空就也去玩了下,刷了一波水TM的YKH就抽到了,我当然是没有了 题目偏水,好像都是1A的.才打了一个半小时,回家就直 ...

  3. EZ 2018 06 02 NOIP2018 模拟赛(十七)

    这次的比赛是真心比较狗,我TM的写了30min的树剖ZZ地直接memset超时了 话说我既然想到差分就应该去写差分的啊! 好了不过这次Rank还挺高的,终于要打进前10了当然是假的了. 好了下面开始讲 ...

  4. 【强化学习】python 实现 saras lambda 例一

    本文作者:hhh5460 本文地址:https://www.cnblogs.com/hhh5460/p/10147265.html 将例一用saras lambda算法重新撸了一遍,没有参照任何其他人 ...

  5. IntelliJ IDEA下自动生成Hibernate映射文件以及实体类

    来自:https://blog.csdn.net/chenyunqiang/article/details/81026823 1.构建项目并添加项目结构配置以及配置初始参数 1.1.如图将基本的架子搭 ...

  6. Vue2.0 搭配 axios

    1.安装axios $ npm install axios 2.Demo (1)Get // 为给定 ID 的 user 创建请求 axios.get('/user?ID=12345') .then( ...

  7. Mesos+Zookeeper+Marathon的Docker管理平台部署记录(1)

    随着"互联网+"时代的业务增长.变化速度及大规模计算的需求,廉价的.高可扩展的分布式x86集群已成为标准解决方案,如Google已经在几千万台服务器上部署分布式系统.Docker及 ...

  8. Visual Studio2013安装过程以及单元测试

    一.安装环境 操作系统版本:Windows10家庭中文版64位 CPU:i5-4200u  1.60GHz 硬盘内存:750G 二.安装版本 Visual Studio2013 三.安装过程 Visu ...

  9. 毕设之c#多线程学习(官方+转载)

    官方文档,原址:打开 如何:对 Windows 窗体控件进行线程安全调用   使用多线程提高 Windows 窗体应用程序的性能时,必须注意以线程安全方式调用控件. 示例 访问 Windows 窗体控 ...

  10. iOS开发线程安全问题

    先来看一下代码: - (void)viewDidLoad { [super viewDidLoad]; self.testStr = @"String initial complete&qu ...