2 条题解

  • 0
    @ 2026-8-19 9:48:57

    神秘启发式合并解法?

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int n;
    vector<int> e[200010];
    int lowbit(int x){
    	return x&(-x);
    }
    struct BIT{
    	int tr[200010];
    	void add(int x,int v){
    		for(int i=x;i<=n;i+=lowbit(i))tr[i]+=v;
    	}
    	int find(int x){
    		int ans=0;
    		for(int i=x;i;i-=lowbit(i))ans+=tr[i];
    		return ans;
    	}
    }tr;
    int sz[200010],son[200010];
    void dfs(int x,int xfa){
    	sz[x]=1;son[x]=-1;
    	for(int y:e[x])if(y^xfa){
    		dfs(y,x);
    		if(son[x]==-1||sz[y]>sz[son[x]])son[x]=y;
    		sz[x]+=sz[y];
    	}
    }
    ll f[200010],g[200010];
    map<pair<int,int>,ll> mp;
    void add(int x,int xfa,int v){
    	tr.add(x,v);
    	for(int y:e[x])if(y^xfa)add(y,x,v);
    }
    void dfs2(int x,int xfa,int fl){
    	for(int y:e[x])if((y^xfa)&&(y^son[x])){
    		dfs2(y,x,1);
    		mp[{x,y}]=tr.find(x-1);
    		add(y,x,-1);
    	}
    	if(~son[x]){
    		dfs2(son[x],x,1);
    		mp[{x,son[x]}]=tr.find(x-1);
    		for(int y:e[x])if((y^xfa)&&(y^son[x])){
    			add(y,x,1);
    		}
    		f[x]=tr.find(x-1);
    	}
    	if(fl)tr.add(x,1);
    	else{
    		for(int y:e[x])if((y^xfa)&&((y^son[x])))add(y,x,-1);
    	}
    	for(int y:e[x])if(y^xfa)g[x]+=g[y]+f[y];
    }
    void dfs3(int x,int xfa){
    	for(int y:e[x])if(y^xfa){
    		g[y]+=g[x]-g[y]-f[y]+x-1-mp[{x,y}];
    		dfs3(y,x);
    	}
    }
    int main(){
    	ios::sync_with_stdio(0);
    	cin.tie(0);
    	cin>>n;
    	for(int i=1,x,y;i<n;i++){
    		cin>>x>>y;
    		e[x].push_back(y);
    		e[y].push_back(x);
    	}
    	dfs(4,0);
    	dfs2(4,0,0);
    	dfs3(4,0);
    	for(int i=1;i<=n;i++){
    		cout<<g[i]+i-1<<" \n"[i==n];
    	}
    	return 0;
    }
    
    • 0
      @ 2026-8-15 10:22:19

      经典换根 DP + 二维偏序题。

      f[x]f[x] 预处理答案,g[x]g[x]xx 子树下比 xx 小的点的个数,h[x]h[x]xx 子树下比 fa[x]fa[x] 小的点的个数。

      #include<bits/stdc++.h>
      using namespace std;
      #define int long long
      const int N=2e5+10;
      vector<int>G[N];
      int n;
      struct BIT
      {
      	int c[N];
      	void add(int x,int k){for(;x<=n;x+=x&-x)c[x]+=k;}
      	int get(int x){if(x<0)return 0;int ans=0;for(;x;x-=x&-x)ans+=c[x];return ans;}
      }tr;
      int f[N],g[N],h[N],dp[N];
      void dfs(int x,int fa)
      {
      	g[x]-=tr.get(x-1);h[x]-=tr.get(fa-1);
      	tr.add(x,1);
      	for(int y:G[x])if(y!=fa)
      	{
      		dfs(y,x);
      		f[x]+=f[y];
      	}
      	g[x]+=tr.get(x-1);f[x]+=g[x];h[x]+=tr.get(fa-1);
      }
      void dfs2(int x,int fa)
      {
      	for(int y:G[x])if(y!=fa)
      	{
      		dp[y]=dp[x]+tr.get(y-1)-g[y]-h[y];
      		dfs2(y,x);
      	}
      }
      signed main()
      {
      	cin>>n;
      	for(int i=1;i<n;i++)
      	{
      		int x,y;cin>>x>>y;
      		G[x].push_back(y);
      		G[y].push_back(x);
      	}
      	dfs(1,0);
      	dp[1]=f[1];dfs2(1,0);
      	for(int i=1;i<=n;i++)cout<<dp[i]<<' ';cout<<'\n';
      	return 0;
      }
      • 1

      信息

      ID
      8254
      时间
      2000ms
      内存
      1024MiB
      难度
      10
      标签
      递交数
      10
      已通过
      3
      上传者