spoj1825 Free tour II

题目链接

一道神奇的点分治

貌似有很多做法,我觉得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 }
原文地址:https://www.cnblogs.com/HugeGun/p/5197023.html