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);
    	}
    }
    
    
  • 相关阅读:
    从句分析
    artDialog ( v 6.0.2 ) content 参数引入页面 html 内容
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 11 盛最多水的容器
    Java实现 LeetCode 11 盛最多水的容器
  • 原文地址:https://www.cnblogs.com/cx233666/p/10368513.html
Copyright © 2011-2022 走看看