【10.26测试爆零记录&瞎扯题解】

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/zxyoi_dreamer/article/details/102758431

T1:

反正结论就是输入 n n 就输出 n n

我考场上用的概率生成函数+组合等式毒瘤变形推出来的,不建议大家尝试。。。

今天T1浪费的时间有点多,导致T3暴力挂掉了

证明考虑期望的线性性,在某一个维度上进行一次平移就行了。

T2:

考场上想了两个 log \log 发现有90分就不想管了,20分钟写完走人。

发现我差分一下就是正解。。。

首先还是观察性质,设 T 1 , T 2 T_1,T_2 表示题目给出的两棵树, T 2 T_2 中的一条边对 T 1 T_1 中的一条边有贡献当且仅当它们互相都在对方的覆盖路径上。(看不懂不要问,反正我自己懂,题解上面也有解释

于是把 T 2 T_2 的边放到 T 1 T_1 上树上差分,然后询问一下 T 1 T_1 中的这条边在 T 2 T_2 中覆盖的路径上有多少点存活。

单点加,链求和,差分一下转化为子树加,单点求和,由于我们只需要子树内部的信息,在dfs的时候利用时间差分一次即可,于是可以用树状数组小常数维护。听说std写的线段树合并MLE了

代码:

#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const

namespace IO{
	inline char gc(){
		static cs int Rlen=1<<22|1;
		static char buf[Rlen],*p1,*p2;
		return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
	}
	
	template<typename T>
	inline T get(){
		char c;T num;
		while(!isdigit(c=gc()));num=c^48;
		while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
		return num;
	}
	inline int gi(){return get<int>();}
}
using namespace IO;

using std::cerr;
using std::cout;
typedef std::pair<int,int> pii;
#define fi first
#define se second

int n;
namespace T2{
	cs int N=1e6+7;
	int el[N],nxt[N<<1],to[N<<1],ec;
	inline void adde(int u,int v){
		nxt[++ec]=el[u],el[u]=ec,to[ec]=v;
		nxt[++ec]=el[v],el[v]=ec,to[ec]=u;
	}
	int in[N],out[N],dfn;
	int fa[N],d[N],son[N],siz[N],top[N];
	void dfs1(int u,int p){
		fa[u]=p,d[u]=d[p]+1;
		for(int re e=el[u],v=to[e];e;v=to[e=nxt[e]])
		if(v!=p){
			dfs1(v,u),siz[u]+=siz[v];
			if(siz[v]>siz[son[u]])son[u]=v;
		}++siz[u];
	}
	void dfs2(int u,int tp){
		top[u]=tp;in[u]=++dfn;
		if(son[u])dfs2(son[u],tp);
		for(int re e=el[u],v=to[e];e;v=to[e=nxt[e]])
		if(v!=fa[u]&&v!=son[u])dfs2(v,v);out[u]=dfn;
	}
	inline int LCA(int u,int v){
		while(top[u]!=top[v])d[top[u]]<d[top[v]]?v=fa[top[v]]:u=fa[top[u]];
		return d[u]<d[v]?u:v;
	}
	void init(){dfs1(1,0);dfs2(1,1);}
}

namespace BIT{
	cs int N=1e6+7;int tr[N];
	inline void add(int p,int v){for(;p<=n;p+=p&-p)tr[p]+=v;}
	inline int query(int p){int r=0;for(;p;p&=p-1)r+=tr[p];return r;}
}

namespace T1{
	cs int N=1e6+7;
	int el[N],nxt[N<<1],to[N<<1],ec=1;
	inline void adde(int u,int v){
		nxt[++ec]=el[u],el[u]=ec,to[ec]=v;
		nxt[++ec]=el[v],el[v]=ec,to[ec]=u;
	}
	int fa[N],d[N],son[N],siz[N],top[N];
	void dfs1(int u,int p){
		fa[u]=p,d[u]=d[p]+1;
		for(int re e=el[u],v=to[e];e;v=to[e=nxt[e]])
		if(v!=p){
			dfs1(v,u),siz[u]+=siz[v];
			if(siz[v]>siz[son[u]])son[u]=v;
		}++siz[u];
	}
	void dfs2(int u,int tp){
		top[u]=tp;
		if(son[u])dfs2(son[u],tp);
		for(int re e=el[u],v=to[e];e;v=to[e=nxt[e]])
		if(v!=fa[u]&&v!=son[u])dfs2(v,v);
	}
	inline int LCA(int u,int v){
		while(top[u]!=top[v])d[top[u]]<d[top[v]]?v=fa[top[v]]:u=fa[top[u]];
		return d[u]<d[v]?u:v;
	}
	void init(){dfs1(1,0);dfs2(1,1);}
	
	int ans[N];
	std::vector<int> ins[N],del[N];
	void work(int u,int p,int eid){
		int lca;
		if(eid){
			lca=T2::LCA(u,p);
			ans[eid]=BIT::query(T2::in[u])+BIT::query(T2::in[p])-BIT::query(T2::in[lca])*2;
		}
		for(int re e=el[u],v=to[e];e;v=to[e=nxt[e]])
		if(v!=p)work(v,u,e>>1);
		for(int re i=0;i<ins[u].size();++i){
			BIT::add(T2::in[ins[u][i]],1);
			BIT::add(T2::out[ins[u][i]]+1,-1);
		}
		for(int re i=0;i<del[u].size();++i){
			BIT::add(T2::in[del[u][i]],-2);
			BIT::add(T2::out[del[u][i]]+1,2);
		}
		if(eid){
			ans[eid]=BIT::query(T2::in[u])+BIT::query(T2::in[p])-BIT::query(T2::in[lca])*2-ans[eid];
		}
	}
	
	void solve(){
		init();
		for(int re i=2;i<=n;++i){
			ins[i].push_back(i);
			ins[T2::fa[i]].push_back(i);
			del[LCA(i,T2::fa[i])].push_back(i);
		}
		work(1,0,0);
		for(int re i=1;i<n;++i)cout<<ans[i]<<" ";
	} 
}

signed main(){
#ifdef zxyoi
	freopen("road.in","r",stdin);
#else
#ifndef ONLINE_JUDGE
	freopen("road.in","r",stdin);freopen("road.out","w",stdout);
#endif
#endif
int size=40<<20;//40M
    //__asm__ ("movl  %0, %%esp\n"::"r"((char*)malloc(size)+size));//调试用这个 
    __asm__ ("movq %0,%%rsp\n"::"r"((char*)malloc(size)+size));//提交用这个 
	n=gi();
	for(int re i=1;i<n;++i)T1::adde(gi(),gi());
	for(int re i=1;i<n;++i)T2::adde(gi(),gi());
	T2::init();T1::solve();
	exit(0);
}

T3:

非常诡异的倍增,做法自己看题解,主要是细节有点多,这里扔一个代码:

#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const
#define int ll
namespace IO{
	inline char gc(){
		static cs int Rlen=1<<22|1;
		static char buf[Rlen],*p1,*p2;
		return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
	}
	
	template<typename T>
	inline T get(){
		char c;T num;
		while(!isdigit(c=gc()));num=c^48;
		while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
		return num;
	}
	inline int gi(){return get<int>();}
}
using namespace IO;

using std::cerr;
using std::cout;
using pii=std::pair<int,int>;
#define fi first
#define se second

cs int N=2e5+7,INF=1e9+1e7;

int n,m,Q;
std::vector<int> G[N];
std::vector<int> pre[N];
int siz[N],rk[20][N];
int to[20][N],son[N],lim[N];
int d[N],q[N],qn;

int go(int s,int k){
	if(!k)return s;
	for(int re i=lim[s];~i;--i){
		if(rk[i][s]<=k&&rk[i][s]+siz[to[i][s]]>=k)
			return go(to[i][s],k-rk[i][s]);
	}
	int p=std::lower_bound(pre[s].begin(),pre[s].end(),k)-pre[s].begin();
	return go(G[s][p],k-(p?pre[s][p-1]:0)-1);
}

signed main(){
#ifdef zxyoi
	freopen("treasure.in","r",stdin);
#endif
	n=gi(),m=gi();
	for(int re i=1;i<=m;++i){
		int u=gi(),v=gi();++d[v];
		G[u].push_back(v);
	}
	for(int re i=1;i<=n;++i)if(!d[i])q[++qn]=i;
	for(int re i=1;i<=qn;++i){
		int u=q[i];for(int v:G[u])if(!--d[v])q[++qn]=v;
	}
	for(int re i=qn;i;--i){
		int u=q[i];ll rec=0;
		for(int re v:G[u]){
			if(siz[v]>siz[son[u]])son[u]=v,rec=siz[u]+1;
			siz[u]+=siz[v]+1;siz[u]=std::min(siz[u],INF);	
			pre[u].push_back(siz[u]);
		}to[0][u]=son[u],rk[0][u]=rec;
		for(int re &j=(lim[u]=0);to[j][u];++j){
			to[j+1][u]=to[j][to[j][u]];
			rk[j+1][u]=rk[j][to[j][u]]+rk[j][u];
			rk[j+1][u]=std::min(rk[j+1][u],INF);
		}--lim[u];
	}Q=gi();
	while(Q--){
		int s=gi(),k=gi();
		if(k>siz[s]){cout<<"-1\n";continue;}
		cout<<go(s,k)<<"\n";
	}
	return 0;
}

吐槽:

怎么说呢,今天算是最近几场里面翻车比较大的一次,T3暴力挂成了0分。

然而这是因为T1用了非常毒瘤的推法推了一个半小时,然后后面时间就感觉有点不够用了,前3分钟T3才调过样例,然而样例太弱挂成0分。。。

L:你简单题做少了

我:。。。

我TM还能说什么。。。

猜你喜欢

转载自blog.csdn.net/zxyoi_dreamer/article/details/102758431