zoukankan      html  css  js  c++  java
  • 【2021.5.8 NOI模拟】贪心

    交互题。

    一棵有根树(不知道根)。保证不存在点恰好有一个儿子。需要确定树的形态。

    每次可以询问一个长度任意的序列,表示将这些序列中的点顺序加入,记个计数器(cnt),如果之前没有假如和它互为祖先后代关系的点,则(cnt+1)。返回(cnt)

    (nle 3000)

    不超过(45000)次询问。


    给节点标号,满足:1. 标号相同的点在同一条祖先后代链上。2. 任意点的祖先的标号都小于等于这个点。

    用阳间的说法来说:维护个链剖分,同一条链上的标号相同,上面的链标号小于下面的链。

    增量造,假设之前加入的点已经标了(1dots k),标号为(i)的集合为(S_i),当前加入点(x)

    (ask(x,S_k,dots,S_1)),如果查出(k+1),则另开标号。(因为(kdots 1),相当于是从下往上扫链,于是这些链不会互相影响)。

    否则,二分出最小的(c)(ask(x,S_c,dots,S_1)=c),于是找到了(x)所在的链。(注意不要找(S_n,dots,S_c),因为后面的可能是(x)的后代,也能和(x)冲突。只有从前往后第一个与(x)冲突的才是(x)所在的链。)

    上面这部分大概用了(k+(n-k)lg n)次。

    最终我们得到了所有点的标号。按照标号顺序从大到小还原:之前有标号更大的,但是链顶没有确定父亲的链,将这些链顶和当前标号下每个点查询,通过结果,就可以知道多少个链顶是它的后代。算出之后排序,能知道链的顺序,然后从深到浅,分治找出每个点的儿子。

    下面这部分大概用了(n+klg n)次。


    #include "greedy.h"
    #include <bits/stdc++.h>
    using namespace std;
    namespace Subtask5{
    	const int N=3005;
    	int vec[N],nv;
    	vector<int> q[N];
    	void ins(vector<int> &p){
    		for (int i=0;i<p.size();++i)
    			vec[nv++]=p[i];
    	}
    	int n,k;
    	bool bz[N];
    	int w[N];
    	bool cmpw(int a,int b){return w[a]<w[b];}
    	int p[N],cnt,tot,del;
    	int fa[N];
    	void lk(int x,int l,int r,int c){
    		if (l==r){
    			bz[p[l]]=1;
    			fa[q[p[l]][q[p[l]].size()-1]]=x;
    			++del;
    			return;
    		}
    		int mid=l+r>>1;
    		nv=0,vec[nv++]=x;
    		for (int i=l;i<=mid;++i)
    			ins(q[p[i]]);
    		int tmp=(mid-l+1)-(ask(nv,vec)-1);
    		if (tmp) lk(x,l,mid,tmp);
    		if (c-tmp) lk(x,mid+1,r,c-tmp);
    	}
    	void work(int _n){
    		n=_n;
    		for (int x=1;x<=n;++x){
    			nv=0,vec[nv++]=x;
    			for (int i=k;i>=1;--i)
    				ins(q[i]);
    			int tmp=ask(nv,vec);
    			if (tmp==k+1)
    				q[++k].push_back(x);
    			else{
    				int l=1,r=k-1,y=k;
    				while (l<=r){
    					int mid=l+r>>1;
    					nv=0,vec[nv++]=x;
    					for (int i=mid;i>=1;--i)
    						ins(q[i]);
    					tmp=ask(nv,vec);
    					if (tmp==mid+1)
    						l=mid+1;
    					else
    						r=(y=mid)-1;
    				}
    				q[y].push_back(x);
    			}
    		}
    		for (int i=k;i>=1;--i){
    			tot=0;
    			nv=1;
    			for (int j=k;j>i;--j)
    				if (!bz[j])
    					ins(q[j]),++tot;
    			for (int t=0;t<q[i].size();++t){
    				int x=q[i][t];
    				vec[0]=x;
    				int tmp=ask(nv,vec);
    				w[x]=tot-(tmp-1);
    			}
    			sort(q[i].begin(),q[i].end(),cmpw);
    			del=0;
    			for (int t=0;t<q[i].size();++t){
    				int x=q[i][t];
    				if (t+1<q[i].size())
    					fa[x]=q[i][t+1];
    				if (t){
    					cnt=0;
    					for (int j=k;j>i;--j)
    						if (!bz[j])
    							p[++cnt]=j;
    					lk(x,1,cnt,w[x]-del);
    				}
    			}
    		}
    		answer(fa+1);
    	}
    }
    void solve(int n,int ty){
    	Subtask5::work(n);
    }
    
  • 相关阅读:
    windows下面安装Python和pip终极教程
    windows下面安装Python和pip终极教程
    JSON格式的服务接口
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/jz-597/p/14748643.html
Copyright © 2011-2022 走看看