一道神奇的点分治
貌似有很多做法,我觉得BIT要好些一些(雾
要求经过黑点数<k就用BIT区间查询前缀
对于每个点用 BIT[0,k-经过黑点数]的最大值+路径长度
使用点分治做到O(n*log22n)
貌似还有O(nlog2n)的做法(雾
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 cint inf=2147483647; 27 void inin(int &ret) 28 { 29 ret=0;int f=0;char ch=getchar(); 30 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=1;ch=getchar();} 31 while(ch>=‘0‘&&ch<=‘9‘)ret*=10,ret+=ch-‘0‘,ch=getchar(); 32 ret=f?-ret:ret; 33 } 34 int head[200020],next[400040],zhi[400040],w[200020],si[200020],v[400040],ed; 35 int shu[200020],dis[200020],col[200020],bo[200020]; 36 int cc[200020],t[200020]; 37 int n,m,k,sum,ans,root,T; 38 void add(int a,int b,int c) 39 { 40 next[++ed]=head[a],head[a]=ed,zhi[ed]=b,v[ed]=c; 41 next[++ed]=head[b],head[b]=ed,zhi[ed]=a,v[ed]=c; 42 } 43 void getroot(int x,int fa) 44 { 45 w[x]=0,si[x]=1; 46 for(int i=head[x];i;i=next[i])if(!bo[zhi[i]]&&zhi[i]!=fa) 47 { 48 getroot(zhi[i],x); 49 si[x]+=si[zhi[i]]; 50 w[x]=max(w[x],si[zhi[i]]); 51 } 52 w[x]=max(w[x],sum-si[x]); 53 if(w[x]<w[root])root=x; 54 } 55 int lowbit(int x){return x&-x;} 56 int query(int r) 57 { 58 int ret=-inf;r++; 59 while(r) 60 { 61 if(t[r]==T)ret=max(ret,cc[r]); 62 r-=lowbit(r); 63 } 64 return ret; 65 } 66 void add_(int c,int x) 67 { 68 c++; 69 while(c<=k+1) 70 { 71 if(t[c]==T)cc[c]=max(cc[c],x); 72 else t[c]=T,cc[c]=x; 73 c+=lowbit(c); 74 } 75 } 76 void getans(int x,int fa) 77 { 78 if(shu[x]-col[root]>k)return ; 79 int hh=query(k-shu[x]+col[root]); 80 if(hh!=-inf)ans=max(ans,hh+dis[x]); 81 for(int i=head[x];i;i=next[i])if(!bo[zhi[i]]&&zhi[i]!=fa) 82 dis[zhi[i]]=dis[x]+v[i],shu[zhi[i]]=col[zhi[i]]+shu[x],getans(zhi[i],x); 83 } 84 void add(int x,int fa) 85 { 86 if(shu[x]-col[root]>k)return ; 87 add_(shu[x],dis[x]); 88 for(int i=head[x];i;i=next[i])if(!bo[zhi[i]]&&zhi[i]!=fa) 89 add(zhi[i],x); 90 } 91 void solve(int x) 92 { 93 T++; 94 bo[x]=1;add_(col[x],0); 95 for(int i=head[x];i;i=next[i])if(!bo[zhi[i]]) 96 { 97 shu[zhi[i]]=col[x]+col[zhi[i]],dis[zhi[i]]=v[i]; 98 getans(zhi[i],x); 99 add(zhi[i],x); 100 } 101 for(int i=head[x];i;i=next[i])if(!bo[zhi[i]]) 102 root=0,sum=si[zhi[i]],getroot(zhi[i],0),solve(root); 103 } 104 int CSC() 105 { 106 inin(n),inin(k),inin(m); 107 re(i,1,m) 108 { 109 int x;inin(x); 110 col[x]=1; 111 } 112 re(i,2,n) 113 { 114 int q,w,e; 115 inin(q),inin(w),inin(e); 116 add(q,w,e); 117 } 118 w[0]=sum=n; 119 getroot(1,0); 120 re(i,1,k+1)cc[i]=-inf; 121 ans=-inf; 122 solve(root); 123 printf("%d",max(ans,0)); 124 return 0; 125 }
时间: 2024-10-15 06:58:28