[Codeforces] 463E. Caisa and Tree

題目連結:http://codeforces.com/problemset/problem/463/E
某種DP感的東東,我的作法大概就是先篩好質因數表,接著DFS下去的時候就把每個數的質因數塞到某個set之類的裡面,而在塞之前可以看一下是不是有前面的人有這個質因數了,然後紀錄一下就好了XD
#include <bits/stdc++.h>
using namespace std;
#define PB push_back
typedef pair<int,int> PII;
#define FF first
#define SS second
const int C = 2000000 + 5;
const int N = 100000 + 5;

bool notprime[C];
vector<int> frac[C], G[N];
int arr[N], ans[N], dep[N], mp[C];
inline void sieve(int);
void dfs(int,int);

int main(){
	ios_base::sync_with_stdio(0);cin.tie(0);
	sieve(C);
	memset(mp, -1, sizeof(mp));
	int n, q; cin>>n>>q;
	for(int i=1;i<=n;i++) cin>>arr[i];
	for(int i=0;i<n-1;i++){
		int u, v; cin>>u>>v;
		G[u].PB(v);
		G[v].PB(u);
	}
	dep[1]=1;
	dfs(1, 1);
	while(q--){
		int tp; cin>>tp;
		if(tp==1){
			int v; cin>>v;
			cout<<ans[v]<<'\n';
		}else{
			int v, w; cin>>v>>w;
			arr[v]=w;
			dfs(1, 1);
		}
	}
	return 0;
}

inline void sieve(int n){
	for(int i=2;i<n;i++){
		if(!notprime[i]){
			frac[i].PB(i);
			for(int j=i+i;j<n;j+=i){
				frac[j].PB(i);
				notprime[j]=1;
			}
		}
	}
}

void dfs(int w, int f){
	dep[w]=dep[f]+1;
	auto &ret = ans[w];
	ret=-1;
	vector<PII> qq;
	for(auto i: frac[arr[w]]){
		qq.PB({i, mp[i]});
		if(mp[i]!=-1) if(ret == -1 or dep[mp[i]] > dep[ret])
			ret = mp[i];
		mp[i]=w;
	}
	for(auto i: G[w]) if(i!=f) dfs(i, w);
	for(auto i: qq) mp[i.FF]=i.SS;
}

留言

這個網誌中的熱門文章

[NPSC] 2009初賽 E. 檸檬汽水傳說

[TIOJ] 1902. 「殿仁.王,不認識,誰啊?」,然後他就死了……

[AtCoder] [經典競程 90 題] 024 - Select +/- One(★2)