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; }