去年NOIP的时候我还不会树链剖分!
还是被UOJ 的数据卡了一组。
差分的思想还是很神啊!
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #include <ctime> 6 #include <cstdlib> 7 using namespace std; 8 const int Maxn=300100; 9 const int Inf=0x3f3f3f3f; 10 int n,m,u,v,w,cnt,tot,MaxLen,MinLen,Minw,Maxw,Ans; 11 int head[Maxn],dep[Maxn],siz[Maxn],father[Maxn],W[Maxn],p[Maxn],q[Maxn],dis[Maxn],Len[Maxn],c[Maxn],top[Maxn],Memory[Maxn],Root; 12 struct Edge{int to,next,w;}edge[Maxn<<1]; 13 inline void Get_Int(int &x) 14 { 15 x=0; char ch=getchar(); int f=1; 16 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 17 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} x*=f; 18 } 19 inline void Put_Int(int x) 20 { 21 char ch[20]; int top=0; 22 if (x==0) ch[++top]='0'; 23 while (x) ch[++top]=x%10+'0',x/=10; 24 while (top) putchar(ch[top--]); putchar('\n'); 25 } 26 inline int Max(int x,int y) {return x>y?x:y;} 27 inline int Min(int x,int y) {return x>y?y:x;} 28 inline void Add(int u,int v,int w) 29 {edge[cnt].to=v;edge[cnt].next=head[u];edge[cnt].w=w;head[u]=cnt++;} 30 //============================================== 31 void Dfs1(int u,int fa) 32 { 33 siz[u]=1; 34 for (int i=head[u];i!=-1;i=edge[i].next) 35 if (edge[i].to!=fa) 36 { 37 dep[edge[i].to]=dep[u]+1; 38 father[edge[i].to]=u; 39 dis[edge[i].to]=dis[u]+edge[i].w; 40 W[edge[i].to]=edge[i].w; 41 Dfs1(edge[i].to,u); 42 siz[u]+=siz[edge[i].to]; 43 } 44 } 45 void Dfs2(int u,int chain,int fa) 46 { 47 top[u]=chain; int k=0; 48 for (int i=head[u];i!=-1;i=edge[i].next) 49 if (edge[i].to!=fa && (siz[edge[i].to]>siz[k] || k==0)) k=edge[i].to; 50 if (k==0) return; 51 Dfs2(k,chain,u); 52 for (int i=head[u];i!=-1;i=edge[i].next) 53 if (edge[i].to!=fa && k!=edge[i].to) Dfs2(edge[i].to,edge[i].to,u); 54 } 55 inline int Lca(int u,int v) 56 { 57 while (true) 58 { 59 if (top[u]==top[v]) return dep[u]>dep[v]?v:u; 60 if (dep[top[u]]>dep[top[v]]) u=father[top[u]]; else v=father[top[v]]; 61 } 62 } 63 int Get(int u,int f) 64 { 65 for (int i=head[u];i!=-1;i=edge[i].next) 66 if (f!=edge[i].to) 67 c[u]+=Get(edge[i].to,u); 68 if (c[u]==tot) MinLen=Max(MinLen,W[u]); 69 return c[u]; 70 } 71 inline bool Check(int t) 72 { 73 MaxLen=MinLen=tot=0; 74 memset(c,0,sizeof(c)); 75 for (int i=1;i<=m;i++) 76 if (Len[i]>t) 77 { 78 c[p[i]]++,c[q[i]]++; 79 c[Lca(p[i],q[i])]-=2; 80 MaxLen=Max(MaxLen,Len[i]); 81 tot++; 82 } 83 if (Memory[tot]) 84 { 85 if (Memory[tot]<=t) return true; 86 return false; 87 } 88 Get(Root,Root); 89 Memory[tot]=(MaxLen-MinLen); 90 if (Memory[tot]<=t) return true; 91 return false; 92 } 93 int main() 94 { 95 srand(time(0)); 96 Get_Int(n),Get_Int(m); 97 memset(head,-1,sizeof(head)); Minw=Inf; 98 for (int i=1;i<n;i++) 99 { 100 Get_Int(u),Get_Int(v),Get_Int(w); 101 Add(u,v,w),Add(v,u,w); 102 Minw=Min(Minw,w); 103 } 104 for (int i=1;i<=m;i++) Get_Int(p[i]),Get_Int(q[i]); 105 Root=rand()%n+1; 106 father[Root]=Root; dep[Root]=1; dis[Root]=0; 107 Dfs1(Root,Root); 108 Dfs2(Root,Root,Root); 109 memset(Memory,0,sizeof(Memory)); 110 for (int i=1;i<=m;i++) Len[i]=dis[p[i]]+dis[q[i]]-2*dis[Lca(p[i],q[i])],Maxw=Max(Maxw,Len[i]); 111 int l=Minw,r=Maxw; 112 while (l<=r) 113 { 114 int mid=(l+r)>>1; 115 if (Check(mid)) Ans=mid,r=mid-1; else l=mid+1; 116 117 } 118 Put_Int(Ans); 119 return 0; 120 }