樹上三角形
阿新 • • 發佈:2018-11-21
Description
給定一大小為n的有點權樹,每次詢問一對點(u,v),問是否能在u到v的簡單路徑上取三個點權,以這三個權值為邊長構成一個三角形。同時還支援單點修改。
Input
第一行兩個整數n、q表示樹的點數和運算元
第二行n個整數表示n個點的點權
以下n-1行,每行2個整數a、b,表示a是b的父親(以1為根的情況下)
以下q行,每行3個整數t、a、b
若t=0,則詢問(a,b)
若t=1,則將點a的點權修改為b
n,q<=100000,點權範圍[1,2^31-1]
Output
對每個詢問輸出一行表示答案,“Y”表示有解,“N”表示無解。
Sample Input
5 5
1 2 3 4 5
1 2
2 3
3 4
1 5
0 1 3
0 4 5
1 1 4
0 2 5
0 2 3
Sample Output
N
Y
Y
N
這題直接暴力!!!
考慮一下不能湊出三角形的木棍長度排列
1,2,3,5,8,11,...
就是Fibonacci數列,所以路徑長度>50就直接輸出Y,否則暴力判斷。。。
/*program from Wolfycz*/ #include<cmath> #include<cstdio> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #define inf 0x7f7f7f7f using namespace std; typedef long long ll; typedef unsigned int ui; typedef unsigned long long ull; inline char gc(){ static char buf[1000000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++; } inline int frd(){ int x=0,f=1;char ch=gc(); for (;ch<'0'||ch>'9';ch=gc()) if (ch=='-') f=-1; for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<1)+(x<<3)+ch-'0'; return x*f; } inline int read(){ int x=0,f=1;char ch=getchar(); for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1; for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0'; return x*f; } inline void print(int x){ if (x<0) putchar('-'),x=-x; if (x>9) print(x/10); putchar(x%10+'0'); } const int N=1e5; vector<ui>vec; int v[N+10]; struct S1{ int pre[(N<<1)+10],now[N+10],child[(N<<1)+10],tot; int deep[N+10],fa[N+10],Rem[N+10],top[N+10],size[N+10]; void join(int x,int y){pre[++tot]=now[x],now[x]=tot,child[tot]=y;} void insert(int x,int y){join(x,y),join(y,x);} void dfs(int x){ deep[x]=deep[fa[x]]+1,size[x]=1; for (int p=now[x],son=child[p];p;p=pre[p],son=child[p]){ if (son==fa[x]) continue; fa[son]=x,dfs(son); size[x]+=size[son]; if (size[Rem[x]]<size[son]) Rem[x]=son; } } void build(int x){ if (!x) return; top[x]=Rem[fa[x]]==x?top[fa[x]]:x; build(Rem[x]); for (int p=now[x],son=child[p];p;p=pre[p],son=child[p]){ if (son==fa[x]||son==Rem[x]) continue; build(son); } } int Lca(int x,int y){ while (top[x]!=top[y]){ if (deep[top[x]]<deep[top[y]]) swap(x,y); x=fa[top[x]]; } return deep[x]<deep[y]?x:y; } bool work(int x,int y){ int lca=Lca(x,y); if (deep[x]+deep[y]-2*deep[lca]+1>50) return 1; vec.clear(); vec.push_back(v[lca]); for (;x!=lca;x=fa[x]) vec.push_back(v[x]); for (;y!=lca;y=fa[y]) vec.push_back(v[y]); sort(vec.begin(),vec.end()); for (vector<ui>::iterator i=vec.begin();i!=vec.end();i++) for (vector<ui>::iterator j=i+1;j!=vec.end();j++) for (vector<ui>::iterator k=j+1;k!=vec.end();k++) if (*k<*j+*i) return 1; return 0; } }HLD;//Heavy Light Decomposition int main(){ int n=read(),m=read(); for (int i=1;i<=n;i++) v[i]=read(); for (int i=1;i<n;i++){ int x=read(),y=read(); HLD.insert(x,y); } HLD.dfs(1),HLD.build(1); for (int i=1;i<=m;i++){ int type=read(),x=read(),y=read(); if (type==0) printf(HLD.work(x,y)?"Y\n":"N\n"); if (type==1) v[x]=y; } return 0; }