제출 #1287299

#제출 시각아이디문제언어결과실행 시간메모리
1287299trinm01Mergers (JOI19_mergers)C++20
0 / 100
49 ms26268 KiB
// #pragma GCC optimize("O3")
// #pragma GCC optimization("Ofast,unroll-loops")
// #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#include <bits/stdc++.h>
using namespace std;

#define int long long 
#define ll long long
#define FOR(i, l, r) for (int i = (l); i <= (r); i++)
#define FOD(i, r, l) for (int i = (r); i >= (l); i--)
#define fi first
#define se second
#define pii pair<int, int>

const ll mod = 1e9 + 7;
const int MAXN = 5e5 + 5;
const ll oo = 1e18 + 7;  
const int base = 10;

int n, k;
vector<int> adj[MAXN];
int p[MAXN];

int h[MAXN], up[MAXN][20];
void dfs(int u, int p){
	for(auto v:adj[u]){
		if(v==p) continue;
		h[v]=h[u]+1;
		up[v][0]=u;
		FOR(i, 1, 19){
			up[v][i]=up[up[v][i-1]][i-1];
		}
		dfs(v, u);
	}
}
int lca(int u, int v){
	if(h[u]!=h[v]){
		if(h[u]<h[v]){
			swap(u, v);
		}
		int k=(h[u]-h[v]);
		FOR(i, 0, 19){
			if((k>>i)&1){
				u=up[u][i];
			}
		}
	}
	if(u==v) return u;
	FOD(i, 19, 0){
		if(up[u][i]!=up[v][i]){
			u=up[u][i];
			v=up[v][i];
		}
	}
	return up[u][0];
}

int par[MAXN];
int find(int u){
	if(u==par[u]){
		return u;
	}
	return par[u]=find(par[u]);
}
void join(int u, int v){
	u=find(u);
	v=find(v);
	if(u==v){
		return;
	}
	if(h[u]>h[v]) swap(u, v);	
	par[v]=u;
}

void merge1(int u, int p){
	int uu=u;
	while(h[uu]>=h[p]){
		join(u, uu);
		uu=up[find(uu)][0];
	}
}
void merge(int u, int v){
	int p=lca(u, v);
	// cout << u << ' ' << v << ' ' << p << '\n';
	merge1(u, p);
	merge1(v, p);	
}

int last[MAXN];
int cnt[MAXN];

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    
    
    // freopen("test.txt", "r", stdin);
    // freopen("o2.out", "w", stdout);

    if(fopen(".inp", "r")){
        freopen(".inp", "r", stdin);
        freopen(".out", "w", stdout);
    }

    cin >> n >> k;
    FOR(i, 1, n-1){
    	int u, v;
    	cin >> u >> v;
    	adj[u].push_back(v);
    	adj[v].push_back(u);
    }
    FOR(i, 1, n){
    	cin >> p[i];
    }
    h[0]=-1;
    dfs(1, 0);
    FOR(i, 1, n){
    	par[i]=i;
    }
    
    FOR(i, 1, n){
    	if(last[p[i]]){
    		merge(last[p[i]], i);
    	}
    	last[p[i]]=i;
    }
    
    FOR(u, 1, n){
    	for(auto v:adj[u]){
    		if(find(u)!=find(v)){
    			cnt[v]++;
    		}
    	}
    }
    int ans=0;
    FOR(i, 1, n){
    	if(cnt[i]==1){
    		ans++;
    	}
    }
    cout << (ans+1)/2;
    
    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

mergers.cpp: In function 'int main()':
mergers.cpp:102:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  102 |         freopen(".inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~
mergers.cpp:103:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  103 |         freopen(".out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...