首页 > 技术文章 > 2018年牛客网NOIP赛前训练营游记

skylee03 2018-09-10 13:14 原文

2018年牛客网NOIP赛前训练营游记

提高组(第一场)

中位数

#include<cstdio>
#include<cctype>
#include<climits>
#include<algorithm>
inline int getint() {
	register char ch;
	while(!isdigit(ch=getchar()));
	register int x=ch^'0';
	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
	return x;
}
const int N=1e5+1;
int n,len,a[N],tmp[N],b[N];
inline bool check(const int &k) {
	for(register int i=1;i<=n;i++) {
		b[i]=b[i-1]+(a[i]<k?-1:1);
	}
	int min=INT_MAX;
	for(register int i=len;i<=n;i++) {
		min=std::min(min,b[i-len]);
		if(b[i]-min>0) return true;
	}
	return false;
}
int main() {
	n=getint(),len=getint();
	for(register int i=1;i<=n;i++) {
		tmp[i]=a[i]=getint();
	}
	std::sort(&tmp[1],&tmp[n]+1);
	tmp[0]=std::unique(&tmp[1],&tmp[n]+1)-&tmp[1];
	for(register int i=1;i<=n;i++) {
		a[i]=std::lower_bound(&tmp[1],&tmp[tmp[0]]+1,a[i])-tmp;
	}
	int l=2,r=tmp[0];
	while(l<=r) {
		const int mid=(l+r)>>1;
		if(check(mid)) {
			l=mid+1;
		} else {
			r=mid-1;
		}
	}
	printf("%d\n",tmp[l-1]);
	return 0;
}

保护

#include<cstdio>
#include<cctype>
#include<vector>
inline int getint() {
	register char ch;
	while(!isdigit(ch=getchar()));
	register int x=ch^'0';
	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
	return x;
}
const int N=2e5+1,logN=20;
struct Node {
	int k,id;
};
std::vector<int> e[N];
std::vector<Node> q[N];
inline void add_edge(const int &u,const int &v) {
	e[u].push_back(v);
	e[v].push_back(u);
}
int n,anc[N][logN],dep[N],dfn[N],id[N],ans[N];
inline int lg2(const float &x) {
	return ((unsigned&)x>>23&255)-127;
}
void dfs(const int &x,const int &par) {
	anc[x][0]=par;
	dep[x]=dep[par]+1;
	dfn[x]=++dfn[0];
	id[dfn[x]]=x;
	for(register int i=1;i<=lg2(dep[x]);i++) {
		anc[x][i]=anc[anc[x][i-1]][i-1];
	}
	for(auto &y:e[x]) {
		if(y!=par) dfs(y,x);
	}
}
inline int lca(int x,int y) {
	if(dep[x]<dep[y]) std::swap(x,y);
	for(register int i=lg2(dep[x]-dep[y]);i>=0;i--) {
		if(dep[anc[x][i]]>=dep[y]) x=anc[x][i];
	}
	for(register int i=lg2(dep[x]);i>=0;i--) {
		if(anc[x][i]!=anc[y][i]) {
			x=anc[x][i];
			y=anc[y][i];
		}
	}
	return x==y?x:anc[x][0];
}
class SegmentTree {
	#define mid ((b+e)>>1)
	private:
		struct Node {
			int val,left,right;
		};
		Node node[N*logN*2];
		int sz;
		int new_node() {
			return ++sz;
		}
	public:
		int root[N];
		void insert(int &p,const int &b,const int &e,const int &x) {
			if(!p) p=new_node();
			node[p].val++;
			if(b==e) return;
			if(x<=mid) insert(node[p].left,b,mid,x);
			if(x>mid) insert(node[p].right,mid+1,e,x);
		}
		void merge(int &p,int &q,const int &b,const int &e) {
			if(!p) {
				p=q;
				return;
			}
			if(!q) return;
			node[p].val+=node[q].val;
			if(b==e) return;
			merge(node[p].left,node[q].left,b,mid);
			merge(node[p].right,node[q].right,mid+1,e);
		}
		int query(const int &p,const int &b,const int &e,const int &k) const {
			if(node[p].val<k) return 0;
			if(b==e) return id[b];
			const int &tmp=node[node[p].left].val;
			if(tmp>=k) return query(node[p].left,b,mid,k);
			return query(node[p].right,mid+1,e,k-tmp);
		}
	#undef mid
};
SegmentTree t;
void dfs(const int &x) {
	for(auto &y:e[x]) {
		if(y==anc[x][0]) continue;
		dfs(y);
		t.merge(t.root[x],t.root[y],1,n);
	}
	for(auto &p:q[x]) {
		const int &k=p.k,&id=p.id;
		const int tmp=t.query(t.root[x],1,n,k);
		ans[id]=(tmp&&dep[tmp]<dep[x])?dep[x]-dep[tmp]:0;
	}
}
int main() {
	n=getint();
	const int m=getint();
	for(register int i=1;i<n;i++) {
		add_edge(getint(),getint());
	}
	dfs(1,0);
	for(register int i=0;i<m;i++) {
		const int u=getint(),v=getint(),p=lca(u,v);
		t.insert(t.root[u],1,n,dfn[p]);
		t.insert(t.root[v],1,n,dfn[p]);
	}
	const int c=getint();
	for(register int i=0;i<c;i++) {
		const int x=getint(),k=getint();
		q[x].push_back((Node){k,i});
	}
	dfs(1);
	for(register int i=0;i<c;i++) {
		printf("%d\n",ans[i]);
	}
	return 0;
}

推荐阅读