题目大意(略坑):
初始的一颗数,只有1是有标记的,M v操作表示将v点打上标记,Q v操作表示寻找最靠近v并且打过标记的 点,问进行q次操作后,所有Q操作找到的点的总和为多少
分析:
并查集。每进行一次M操作,vis[v]=1,没进行一次Q就使用并查集去寻找已经打过标记的最近的点,详细看 代码(aizuoj略坑,不要加过多的无用头文件或者其他的)
code:
#include<stdio.h> #include<math.h> #include<cmath> #include<queue> #include<stack> #include<string> #include<cstring> #include<string.h> #include<algorithm> #include<iostream> using namespace std; typedef long long ll; const int maxn =1000000; //------ //define int f[maxn]; int vis[maxn]; //findset int findset(int x) { return vis[x]?x:findset(f[x]); } //solve void solve() { int n,qq,cnt=0; f[1]=0; vis[1]=1; while(cin>>n>>qq&&(n||qq)) { ll tot=0; for(int i=2;i<=n;i++){ cin>>f[i]; vis[i]=0; } for(int i=0;i<qq;i++){ char mark;int t; cin>>mark>>t; if(mark=='Q'){ t=findset(t); tot+=t; }else vis[t]=1; } cout<<tot<<endl; } } int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); solve(); return 0; }