# BZOJ 3251 树上三角形

## Input

n,q<=100000，点权范围[1,2^31-1]

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

N
Y
Y
N

over

# 代码

  1 /*****************************
2 User:Mandy.H.Y
3 Language:c++
4 Problem:Triangle
5 *****************************/
6 //一剑霜寒十四州
7 #include<bits/stdc++.h>
8 #define Max(x,y) ((x) > (y) ? (x) : (y))
9 #define Min(x,y) ((x) < (y) ? (x) : (y))
10
11 using namespace std;
12
13 const int maxn = 1e5 + 5;
14
15 int n,q,size;
16 long long val[maxn];
17 int father[maxn],dep[maxn];
18 int first[maxn],cnt[maxn];
19 int top[maxn];
20 long long cur[maxn];
21
22 struct Edge{
23     int v,nt;
24 }edge[maxn << 1];
25
26 template<class T>inline void read(T &x){
27     x = 0;bool flag = 0;char ch = getchar();
28     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
29     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
30     if(flag) x = -x;
31 }
32
33 template<class T>void putch(const T x){
34     if(x > 9) putch(x / 10);
35     putchar(x % 10 | 48);
36 }
37
38 template<class T>void put(const T x){
39     if(x < 0) putchar('-'),putch(-x);
40     else putch(x);
41 }
42
43 void file(){
44     freopen("Triangle.in","r",stdin);
45     freopen("Triangle.out","w",stdout);
46 }
47
49     edge[++size].v = v;
50     edge[size].nt = first[u];
51     first[u] = size;
52 }
53
56     for(int i = 1;i <= n; ++ i) read(val[i]);
57     for(int i = 1;i < n; ++ i){
58         int u,v;
61         father[v] = u;
62     }
63 }
64
65 void dfs(int u){
66     top[u] = u;
67     int son = 0,mcnt = 0;
68     cnt[u] = 1;
69     for(int i = first[u];i;i = edge[i].nt){
70         int v = edge[i].v;
71         dep[v]=dep[u]+1;
72         dfs(v);
73         cnt[u] += cnt[v];
74         if(cnt[v] > mcnt){
75             mcnt = cnt[v];
76             son = v;
77         }
78     }
79     if(son) top[son] = u;
80 }
81
82 int find(int x){
84 }
85
86 int LCA(int x,int y){
87     if(find(x) == find(y)) return dep[x] < dep[y] ? x : y;
88     else return dep[top[x]] < dep[top[y]] ? LCA(x,father[top[y]]) : LCA(y,father[top[x]]);
89 }
90
91 void work(){
92     dep[1] = 1;
93     dfs(1);
94     while(q--){
95         int t;
97         if(t == 0) {
98             int a,b;
100             int anc = LCA(a,b);
101             int num = dep[a]+dep[b]-(dep[anc]<<1)+1;
102             if(num > 50) puts("Y");
103 //一个三角形都没有的条件是很苛刻的
104 //任意三个数中，较小的两个数的和必须小于等于最大的数
105 //这种数列最长应该是斐波那契
106 //而斐波那契在47项就爆int了
107             else{
108                 int tot = 0,fa = a;
109                 while(fa != anc){
110                     cur[++tot] = val[fa];
111                     fa = father[fa];
112                 }
113                 fa = b;
114                 while(fa != anc){
115                     cur[++tot] = val[fa];
116                     fa = father[fa];
117                 }
118                 bool judge = 0;
119                 cur[++tot] = val[anc];
120                 sort(cur + 1,cur + 1 + tot);
121                 for(int i = 3;i <= tot; ++ i){
122                     if(cur[i] < cur[i-1]+cur[i-2]) {
123                         puts("Y");
124                         judge = 1;
125                         break;
126                     }
127                 }
128                 if(!judge) puts("N");
129             }
130         } else {
131             long long a,b;
133             val[a] = b;
134         }
135     }
136 }
137
138 int main(){
139 //    file();
143 }