zoukankan      html  css  js  c++  java
  • JOISC 2017 自然公园

    吐槽

    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);
    	}
    }
    
    
  • 相关阅读:
    微信小程序--数据存储
    微信小程序---setData
    关于MVC中 服务器无法在发送 HTTP 标头之后修改 cookie此类问题的解决
    获取Web项目中的控制器类以及类中Action方法
    使用Attribute限制Action只接受Ajax请求
    Dapper 返回Sql server 自增长ID 标识列SCOPE_IDENTITY
    根据数据库反向生成PD
    Git常用命令大全,迅速提升你的Git水平
    官方VisualStudio.gitignore配置
    Win10-1909删除自带的微软输入法,添加美式键盘
  • 原文地址:https://www.cnblogs.com/cx233666/p/10368513.html
Copyright © 2011-2022 走看看