[bzoj 3251]树上三角形
题意
给定一棵树,q对询问,每次可以修改一个点权,或者问点对间路径上是否有三个点点权可以作为边长组成三角形
题解
这题好像在哪做过???我健忘了
考虑如果一条路径上没有满足这样的三元组,最长是多少。
最坏情况肯定是斐波那契数列
1,1,2,3,5,8,13,21,34….. 然后在点权范围内的长度只有不到50
暴力一下<50的 大于等于50的直接输出Y
#include<map> #include<stack> #include<queue> #include<cstdio> #include<string> #include<vector> #include<cstring> #include<complex> #include<iostream> #include<assert.h> #include<algorithm> using namespace std; #define inf 1001001001 #define infll 1001001001001001001LL #define ll long long #define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl #define gmax(a,b) (a)=max((a),(b)) #define gmin(a,b) (a)=min((a),(b)) #define Ri register int #define gc getchar() #define il inline il int read(){ bool f=true;Ri x=0;char ch;while(!isdigit(ch=gc))if(ch=='-')f=false;while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=gc;}return f?x:-x; } #define gi read() #define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout); struct edge{ int to,next; }e[233333]; int n,q,last[233333],val[233333],dep[233333],p[233333],cnt; int insert(int a,int b){ e[++cnt]=(edge){b,last[a]};last[a]=cnt; } void dfs(int x,int fa){ for(int i=last[x];i;i=e[i].next) if(e[i].to!=fa){ p[e[i].to]=x; dep[e[i].to]=dep[x]+1; dfs(e[i].to,x); } } int main(){ n=gi;q=gi; for(int i=1;i<=n;i++)val[i]=gi; for(int i=1;i<n;i++){ int a=gi,b=gi; insert(a,b);insert(b,a); } dep[1]=1; dfs(1,-1); for(int i=1;i<=q;i++){ int op,a,b;op=gi;a=gi;b=gi; if(!op){ int len=0,q[233]; while(len<50&&a!=b){ if(dep[a]>dep[b])q[++len]=val[a],a=p[a]; else q[++len]=val[b],b=p[b]; } q[++len]=val[a]; if(len>=50){ puts("Y"); }else{ sort(q+1,q+len+1); int k,flag=true; for(k=1;k<len-1;k++){ if((ll)q[k]+q[k+1]>q[k+2]){ puts("Y"); flag=false; break; } } if(flag)puts("N"); } }else{ val[a]=b; } } }