[BZOJ][Tjoi2016&Heoi2016]樹
阿新 • • 發佈:2019-01-30
ring 聯通 標記 esp true -- tchar href tac
Submit: 2109 Solved: 1013
[Submit][Status][Discuss]
輸入第一行兩個正整數N和Q分別表示節點個數和操作次數接下來N-1行,每行兩個正整數u,v(1≤u,v≤n)表示u到v
有一條有向邊接下來Q行,形如“opernum”oper為“C”時表示這是一個標記操作,oper為“Q”時表示這是一個詢
問操作對於每次詢問操作,1 ≤ N, Q ≤ 100000。
1 2
1 3
2 4
2 5
Q 2
C 2
Q 2
Q 5
Q 3
2
2
1
題解:這個題有兩種做法吧 不嫌麻煩就直接無腦維護子樹裏面深度深度最大的位置 比較簡單幾乎可以線性的做法就是 用並查集倒著過來維護聯通 每個點所在聯通快的根就是答案
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <stack> #include <queue> #include <cmath> #include <set> #include <map> #define mp make_pair #define pb push_back #define pii pair<int,int> #define link(x) for(edge *j=h[x];j;j=j->next) #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,r,l) for(int i=r;i>=l;i--) const int MAXN=3e5+10; const double eps=1e-8; #define ll long long using namespace std; struct edge{int t;edge*next;}e[MAXN<<1],*h[MAXN],*o=e; void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;} ll read(){ ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-‘0‘,ch=getchar(); return x*f; } typedef struct node{ int op,x; }node; node d[MAXN]; int fa[MAXN]; int f[MAXN]; int vis[MAXN]; int find1(int x){ if(x==f[x])return x; else return f[x]=find1(f[x]); } void dfs(int x,int pre){ fa[x]=pre; if(!vis[x])f[x]=find1(f[pre]); link(x){ dfs(j->t,x); } } stack<int>s; int main(){ int n=read(),m=read(); int u,v; inc(i,2,n)u=read(),v=read(),add(u,v); char str[11];vis[1]=1; inc(i,1,m){ scanf("%s %d",str,&u); if(str[0]==‘Q‘)d[i].op=1,d[i].x=u; else d[i].op=2,d[i].x=u,vis[u]++; } inc(i,1,n)f[i]=i; dfs(1,0); dec(i,m,1){ if(d[i].op==1)s.push(find1(d[i].x)); else { if(vis[d[i].x]){ vis[d[i].x]--; if(!vis[d[i].x])f[d[i].x]=find1(fa[d[i].x]); } } } while(!s.empty()){ printf("%d\n",s.top()); s.pop(); } }
4551: [Tjoi2016&Heoi2016]樹
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2109 Solved: 1013
[Submit][Status][Discuss]
Description
在2016年,佳媛姐姐剛剛學習了樹,非常開心。現在他想解決這樣一個問題:給定一顆有根樹(根為1),有以下 兩種操作:1. 標記操作:對某個結點打上標記(在最開始,只有結點1有標記,其他結點均無標記,而且對於某個 結點,可以打多次標記。)2. 詢問操作:詢問某個結點最近的一個打了標記的祖先(這個結點本身也算自己的祖 先)你能幫幫他嗎?Input
Output
輸出一個正整數,表示結果
Sample Input
5 51 2
1 3
2 4
2 5
Q 2
C 2
Q 2
Q 5
Q 3
Sample Output
12
2
1
HINT
新加數據9組(By HFLSyzx ),未重測--2016.8.2
[BZOJ][Tjoi2016&Heoi2016]樹