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;

}

  

 

你可能感兴趣的:(ZOJ)