树上三角形 BZOJ3251
分析:
模拟赛T3,其实很水,当时出于某些原因,没有去写这道题...
len>46必定有解
为了满足不是三角形,那么斐波那契数列是最优选择,而斐波那契数列的第46项超过了2^31-1,所以超过46不能选
之后朴素LCA+暴力(暴力我一开始没有想到怎么写...)
附上代码:
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <queue> #include <iostream> #include <cstdlib> using namespace std; #define N 100005 int n,Q,a[N],fa[N],dep[N],head[N],cnt; struct node{int to,next;}e[N<<1]; void add(int x,int y){e[cnt].to=y;e[cnt].next=head[x];head[x]=cnt++;return;} void dfs(int x,int from) { fa[x]=from,dep[x]=dep[from]+1; for(int i=head[x];i!=-1;i=e[i].next) { int to1=e[i].to; if(to1!=from)dfs(to1,x); } } unsigned int q[N]; bool get_lca(int x,int y) { int num=0; while(x!=y) { if(dep[x]<dep[y])swap(x,y); q[++num]=a[x]; x=fa[x]; if(num>50)return 1; } q[++num]=a[x]; sort(q+1,q+num+1); for(int i=1;i<num-1;i++) { if(q[i]+q[i+1]<=q[i+2])continue; return 1; } return 0; } int main() { memset(head,-1,sizeof(head)); scanf("%d%d",&n,&Q); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); add(x,y);add(y,x); } dfs(1,0); while(Q--) { int x,y,z; scanf("%d%d%d",&x,&y,&z); if(!x) { if(!get_lca(y,z))puts("N"); else puts("Y"); }else { a[y]=z; } } return 0; }