1. 程式人生 > >BZOJ 3319 黑白樹

BZOJ 3319 黑白樹

initial bmi nlogn can log blank bzoj std 如果

3319: 黑白樹

Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 557 Solved: 194
[Submit][Status][Discuss]

Description

給定一棵樹,邊的顏色為黑或白,初始時全部為白色。維護兩個操作:
1.查詢u到根路徑上的第一條黑色邊的標號。
2.將u到v 路徑上的所有邊的顏色設為黑色。
Notice:這棵樹的根節點為1

Input

第一行兩個數n,m分別表示點數和操作數。
接下來n-? 1行,每行2個數u,v.表示一條u到v的邊。
接下來m行,每行為以下格式:
1 v 表示第一個操作
2 v u 表示第二種操作

Output

對於每個詢問,輸出相應答案。如果不存在,輸出0。

Sample Input

5 4
1 2
1 3
2 4
2 5
1 2
2 2 3
1 3
1 4

Sample Output

0
2
1

HINT

對於 100% 的數據:n,m<=10^6

看見這道題之後似乎可以用樹剖來打但是$10^6$的數據範圍顯然對於樹剖的巨大常數$O(nlogn)$是無法承受的

這題在$HZOJ$上的數據極其坑爹,卡幾乎所有正解。。。網上找的$BZOJ$標程都$TLE$了。。。

然而不卡暴力..不卡暴力...暴力...(╯‵□′)╯︵┻━┻

目測數據是個菊花圖。。。深度極其的淺導致依靠子樹大小來減少時間消耗的正解被時間與深度相關的暴力程序力壓。。。

最後棄療慫一波用暴力A掉了這題QwQ

暴力袋馬如下:

技術分享
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <iostream>
 5 #include <algorithm>
 6 
 7 const int MAXE=2000010;
 8 const int MAXV=1000010;
 9 
10 struct Edge{
11     int from;
12     int to;
13     int id;
14     Edge* next;
15 }; 16 17 Edge E[MAXE]; 18 Edge* head[MAXV]; 19 Edge* top=E; 20 21 int n; 22 int m; 23 int id[MAXV]; 24 int prt[MAXV]; 25 int deep[MAXV]; 26 bool color[MAXV]; 27 28 void Initialize(); 29 void Insert(int,int,int); 30 int Query(int); 31 void DFS(int,int,int,int); 32 void Modify(int,int); 33 34 int main(){ 35 int a,b,c; 36 Initialize(); 37 DFS(1,0,0,1); 38 for(int i=0;i<m;i++){ 39 scanf("%d%d",&a,&b); 40 if(a==1){ 41 printf("%d\n",Query(b)); 42 } 43 else if(a==2){ 44 scanf("%d",&c); 45 Modify(b,c); 46 } 47 } 48 return 0; 49 } 50 51 void Modify(int x,int y){ 52 while(x!=y){ 53 if(deep[x]<deep[y]) 54 std::swap(x,y); 55 color[id[x]]=true; 56 x=prt[x]; 57 } 58 } 59 60 int Query(int x){ 61 while(x!=1){ 62 if(color[id[x]]) 63 return id[x]; 64 else 65 x=prt[x]; 66 } 67 return 0; 68 } 69 70 void DFS(int root,int prt,int deep,int id){ 71 ::id[root]=id; 72 ::prt[root]=prt; 73 ::deep[root]=deep; 74 for(Edge* i=head[root];i!=NULL;i=i->next){ 75 if(i->to==prt) 76 continue; 77 DFS(i->to,root,deep+1,i->id); 78 } 79 } 80 81 void Initialize(){ 82 int a,b; 83 scanf("%d%d",&n,&m); 84 for(int i=1;i<n;i++){ 85 scanf("%d%d",&a,&b); 86 Insert(a,b,i); 87 Insert(b,a,i); 88 } 89 } 90 91 inline void Insert(int from,int to,int id){ 92 top->id=id; 93 top->to=to; 94 top->from=from; 95 top->next=head[from]; 96 head[from]=top; 97 top++; 98 }
Code

彪乘袋馬可能會在我的GitHub Repository裏更新QwQ

BZOJ 3319 黑白樹