吐槽

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. anglarjs1.6.3+owin 实现验证之一:统一拒绝非登录访问。

    1.anglarjs端在app.js(即anglar的入口js),注册.factory("messageService",使得每次来自html客户端的请求都能带有一个值,如AKey ...

  2. OSC Source Code Innovation Salon(2018.10.20)

    时间:2018.10.20地点:北京 朝阳 浦项中心B座2层

  3. Notes of Daily Scrum Meeting(12.25)

    今天在学姐的帮助下,我们终于把网络连接的部分连通了,这对我们是一个很大的鼓舞,也找到了前期 连不通的问题在哪里,这让我们重新有了进行下去的勇气和决心,我们会在最后这几天把前端和后端结合, 做出我们最后 ...

  4. Linux环境C程序设计

    Linux基础 常用shell命令 命令 说明 命令 说明 man 查看联机帮助 ls 查看目录及文件列表 cp 复制目录或文件 mv 移动目录或文件 cd 改变文件或目录 rm 删除文件或目录 mk ...

  5. np.array与np.ndarray区别

    (Numpy中ndarray和array的区别是什么?我在哪儿能够找到numpy中相应的实现?) 答:Well, np.array is just a convenience function to ...

  6. Redis持久化的两种方式和区别

    该文转载自:http://www.cnblogs.com/swyi/p/6093763.html Redis持久化的两种方式和区别 Redis是一种高级key-value数据库.它跟memcached ...

  7. vue props 用法(转载)

    前面的话 组件接受的选项大部分与Vue实例一样,而选项props是组件中非常重要的一个选项.在 Vue 中,父子组件的关系可以总结为 props down, events up.父组件通过 props ...

  8. 【转】CSS颜色代码大全

    转自http://www.cnblogs.com/axing/archive/2011/04/09/CSS.html FFFFFF #DDDDDD #AAAAAA #888888 #666666 #4 ...

  9. IIS7开启gZip动态压缩

    1.安装动态压缩模块: 安装过程可能的报错:This application has requested the Runtime to terminate it in an unusual way. ...

  10. laravel 共享session问题总结

    我现在有一个A系统已经上线了,但是要开始研发另外一个功能,我打算把这个功能独立成一个B系统出来,放在其他域名下面,打算在这个A系统登录后,里面一个连接跳转到B系统,看到一些资料说用到共享Session ...