BZOJ3251 : 树上三角形

BZOJ AC1000题纪念~~~

 

将x到y路径上的点权从小到大排序

如果不存在b[i]使得b[i]+b[i+1]>b[i+2]则无解

此时b数列增长速度快于斐波那契数列,当达到50项时就会超过int的范围

所以暴力查询,如果路径长度达到50就肯定有解,否则暴力排序检验

 

#include<cstdio>
#include<algorithm>
#define N 100010
using namespace std;
int n,q,i,x,y,op,a[N],d[N],f[N],g[N],nxt[N],v[N],ed,b[N],t;
inline void read(int&a){char ch;while(!(((ch=getchar())>='0')&&(ch<='9')));a=ch-'0';while(((ch=getchar())>='0')&&(ch<='9'))(a*=10)+=ch-'0';}
inline void add(int x,int y){f[v[++ed]=y]=x;nxt[ed]=g[x];g[x]=ed;}
void dfs(int x){d[x]=d[f[x]]+1;for(int i=g[x];i;i=nxt[i])dfs(v[i]);}
inline bool ask(int x,int y){
  for(t=0;x!=y;){
    if(d[x]<d[y])swap(x,y);
    b[++t]=a[x],x=f[x];
    if(t>48)return 1;
  }
  for(b[++t]=a[x],sort(b+1,b+t+1),i=2;i<t;i++)if((long long)b[i-1]+b[i]>b[i+1])return 1;
  return 0;
}
int main(){
  read(n),read(q);
  for(i=1;i<=n;i++)read(a[i]);
  for(i=1;i<n;i++)read(x),read(y),add(x,y);
  dfs(1);
  while(q--){
    read(op),read(x);
    if(op)read(a[x]);else read(y),puts(ask(x,y)?"Y":"N");
  }
  return 0;
}

  

 

posted @ 2015-01-24 13:47  Claris  阅读(272)  评论(0编辑  收藏