• 【CSP-S 2019模拟】题解


    T1:

    考虑当前位于(x,y)(x,y)
    如果走xx,期望多的贡献是(x1)2+(x+1)2/2=1(x-1)^2+(x+1)^2/2=1
    所以ans=nans=n

    找不到代码了

    T2:

    考虑实际上就是两棵树两条边分别在另一棵树上包含另一条边
    把第二棵树的边在第一棵树上差分后再在第二棵树上单点加链求和
    差分一下子树加单点查

    O(nlogn)O(nlogn)

    #include<bits/stdc++.h>
    using namespace std;
    #define cs const
    #define pb push_back
    #define bg begin
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    cs int RLEN=1<<20|1;
    inline char gc(){
    	static char ibuf[RLEN],*ib,*ob;
    	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    	return (ib==ob)?EOF:*ib++;
    }
    inline int read(){
    	char ch=gc();
    	int res=0,f=1;
    	while(!isdigit(ch))f^=ch=='-',ch=gc();
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    	return f?res:-res;
    }
    cs int N=1000005;
    char xxx;
    vector<int> e2[N];
    vector<pii> e1[N];
    int n;
    namespace bit{
    	int tr[N];
    	#define lb(x) (x&(-x))
    	inline void upd(int p,int k){
    		for(;p<=n;p+=lb(p))tr[p]+=k;
    	}
    	inline void update(int l,int r,int k){
    		upd(l,k),upd(r+1,-k);
    	}
    	inline int query(int p){
    		int res=0;
    		for(;p;p-=lb(p))res+=tr[p];
    		return res;
    	}
    	#undef lb
    }
    using bit::update;
    using bit::query;
    int top[N],siz[N],son[N],fa[N],dep[N],in[N],out[N],idx[N],dfn;
    int up[N],ans[N];
    struct EEE{
    	int u,v,lca;
    }E2[N];
    vector<int> p[N],del[N];
    void dfs1(int u){
    	siz[u]=1,son[u]=0;
    	for(int i=0;i<e1[u].size();i++){
    		int v=e1[u][i].fi;
    		if(v==fa[u])continue;
    		fa[v]=u,dep[v]=dep[u]+1;
    		up[v]=e1[u][i].se;
    		dfs1(v),siz[u]+=siz[v];
    		if(siz[v]>siz[son[u]])son[u]=v;
    	}
    }
    void dfs2(int u,int tp){
    	top[u]=tp,in[u]=++dfn;
    	if(son[u])dfs2(son[u],tp);
    	for(int i=0;i<e1[u].size();i++){
    		int v=e1[u][i].fi;
    		if(v==fa[u]||v==son[u])continue;
    		dfs2(v,v);
    	}
    	out[u]=dfn;
    }
    void dfs3(int u){
    	siz[u]=1,son[u]=0;
    	for(int i=0;i<e2[u].size();i++){
    		int v=e2[u][i];
    		if(v==fa[u])continue;
    		fa[v]=u,dep[v]=dep[u]+1;
    		dfs3(v),siz[u]+=siz[v];
    		if(siz[v]>siz[son[u]])son[u]=v;
    	}
    }
    void dfs4(int u,int tp){
    	top[u]=tp,in[u]=++dfn;;
    	if(son[u])dfs4(son[u],tp);
    	for(int i=0;i<e2[u].size();i++){
    		int v=e2[u][i];
    		if(v==fa[u]||v==son[u])continue;
    		dfs4(v,v);
    	}
    	out[u]=dfn;
    }
    inline int Lca(int u,int v){
    	while(top[u]!=top[v]){
    		if(dep[top[u]]<dep[top[v]])swap(u,v);
    		u=fa[top[u]];
    	}
    	return dep[u]>dep[v]?v:u;
    }
    inline int ask(int u,int v){
    	return query(in[u])+query(in[v])-2*query(in[Lca(u,v)]);
    }
    void dfs5(int u,int f){
    	int pre=0;
    	if(u>1)pre=ask(u,f);
    	for(int i=0;i<e1[u].size();i++){
    		int v=e1[u][i].fi;
    		if(v==f)continue;
    		dfs5(v,u);
    	}
    	for(int i=0;i<p[u].size();i++){
    		int x=p[u][i];
    		update(in[x],out[x],1);
    	}
    	for(int i=0;i<del[u].size();i++){
    		int x=del[u][i];
    		update(in[x],out[x],-2);
    	}
    	ans[up[u]]=ask(u,f)-pre;
    }
    char yyy;
    int main(){
    int size=40<<20;//40M
        //__asm__ ("movl  %0, %%esp
    "::"r"((char*)malloc(size)+size));//调试用这个 
        __asm__ ("movq %0,%%rsp
    "::"r"((char*)malloc(size)+size));//提交用这个 
    
        //main函数代码 
    	n=read();
    	for(re int i=1;i<n;i++){
    		int u=read(),v=read();
    		e1[u].pb(pii(v,i)),e1[v].pb(pii(u,i));
    	}
    	for(re int i=1,u,v;i<n;i++){
    		u=read(),v=read();
    		e2[u].pb(v),e2[v].pb(u);
    		E2[i].u=u,E2[i].v=v;
    	}
    	dfs1(1),dfs2(1,1);
    	for(re int i=1;i<n;i++)E2[i].lca=Lca(E2[i].u,E2[i].v);
    	dfn=0,dfs3(1);
    	dfs4(1,1);
    	for(re int i=1,u,v,lca;i<n;i++){
    		u=E2[i].u,v=E2[i].v,lca=E2[i].lca;
    		if(dep[u]<dep[v])swap(u,v);
    		p[u].pb(u),p[v].pb(u),del[lca].pb(u);
    	}
    	dfs5(1,0);
    	for(int i=1;i<n;i++)cout<<ans[i]<<" ";
    	exit(0);
    }
    

    T3:

    DAGDAG上类似重剖,找方案最多的儿子,预处理向下的倍增数组
    这样每次跳必然方案数减半

    O(nlog2n)O(nlog^2n)

    #include<bits/stdc++.h>
    using namespace std;
    #define cs const
    #define pb push_back
    #define bg begin
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    cs int RLEN=1<<20|1;
    inline char gc(){
    	static char ibuf[RLEN],*ib,*ob;
    	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    	return (ib==ob)?EOF:*ib++;
    }
    inline int read(){
    	char ch=gc();
    	int res=0,f=1;
    	while(!isdigit(ch))f^=ch=='-',ch=gc();
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    	return f?res:-res;
    }
    int n,m;
    cs int N=200005;
    int down[N][21],cost[N][21];
    vector<int> e[N],val[N],ss[N];
    int f[N],son[N],in[N],rt;
    cs int lim=1e9+2;
    inline int add(int a,int b){
    	return min(lim,a+b);
    }
    void dfs(int u){
    	if(f[u])return;
    	int hv=0;
    	for(int &v:e[u]){
    		dfs(v);
    		if(f[v]>f[son[u]])son[u]=v,hv=f[u]+1;
    		f[u]=add(f[u],f[v]+1);
    		val[u].pb(f[u]);
    	}
    	down[u][0]=son[u],cost[u][0]=hv;
    	for(int i=1;i<19;i++)down[u][i]=down[down[u][i-1]][i-1],cost[u][i]=add(cost[u][i-1],cost[down[u][i-1]][i-1]);
    }
    int find(int u,int k){
    	if(!k)return u;
    	for(int i=18;~i;i--){
    		if(down[u][i]&&cost[u][i]<=k&&k<=cost[u][i]+f[down[u][i]])
    		return find(down[u][i],k-cost[u][i]);
    	}
    	int pos=lower_bound(val[u].bg(),val[u].end(),k)-val[u].bg();
    	if(!pos)return find(e[u][pos],k-1);
    	return find(e[u][pos],k-val[u][pos-1]-1);
    }
    int main(){
    	#ifdef Stargazer
    	freopen("lx.cpp","r",stdin);
    //	freopen("my.out","w",stdout);
    	#endif
    	n=read(),m=read();
    	for(int i=1;i<=m;i++){
    		int u=read(),v=read();
    		e[u].pb(v),in[v]++;
    	}
    	for(int i=1;i<=n;i++)if(!in[i])rt=i;
    	dfs(rt);
    	int q=read();
    	while(q--){
    		int u=read(),k=read();
    		if(k>f[u]){cout<<-1<<'
    ';}
    		else cout<<find(u,k)<<'
    ';
    	}
    }
    
  • 相关阅读:
    C++ 类 析构函数
    Oracle 11g rac 添加新节点测试
    rac添加新节点的步骤与方法
    X 传输表空间方法留待整理
    1913: 成绩评估
    1066: 输入n个数和输出调整后的n个数
    1005: 渊子赛马
    Problem Y: 哪一天,哪一秒?
    Problem T: 结构体学生信息排序
    Problem O: 国家排序
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328386.html
Copyright © 2020-2023  润新知