luogu P3576 [POI2014]MRO-Ant colony
阿新 • • 發佈:2018-09-22
葉子 mat 傳送門 clu const www oid += 兩個
傳送門
一群螞蟻能被吃,也就是走到指定邊的兩端點之一要走到另一端點時有\(k\)只,我們可以從這兩端點逆推,記兩個值為走到某個點時最後會被吃掉\(k\)只螞蟻的螞蟻數量範圍,式子下面有,很好理解(霧).最後在每個葉子節點二分查找有多少個數在區間內即可
// luogu-judger-enable-o2 #include<bits/stdc++.h> #define LL long long #define il inline #define re register #define inf 2099999999 #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define db double #define eps (1e-5) using namespace std; const int N=1000000+10; il LL rd() { re LL x=0,w=1;re char ch=0; while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();} while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} return x*w; } LL d[N]; int to[N<<1],nt[N<<1],hd[N],tot=1; il void add(int x,int y) { ++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot,++d[x]; ++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot,++d[y]; } int n,g,k,ma,xx,yy; LL ll[N],rr[N],ans,a[N]; void dfs(int x,int ffa) { for(int i=hd[x];i;i=nt[i]) { int y=to[i]; if(y==ffa) continue; ll[y]=min(ll[x]*max(d[x]-1,1ll),a[g]+10),rr[y]=min((rr[x]+1)*max(d[x]-1,1ll)-1,a[g]+10); dfs(y,x); } if(d[x]==1) { int l=0,r=g,z=g,zz=0; while(l<=r) { int mid=(l+r)>>1; if(a[mid]<ll[x]) z=mid,l=mid+1; else r=mid-1; } l=0,r=g; while(l<=r) { int mid=(l+r)>>1; if(a[mid]<=rr[x]) zz=mid,l=mid+1; else r=mid-1; } ans+=max(zz-z,0); } } int main() { n=rd(),g=rd(),k=rd(); for(int i=1;i<=g;i++) a[i]=rd(); sort(a+1,a+g+1); a[0]=-1; add(xx=rd(),yy=rd()); for(int i=2;i<n;i++) add(rd(),rd()); ll[xx]=rr[xx]=k,dfs(xx,yy); ll[yy]=rr[yy]=k,dfs(yy,xx); printf("%lld\n",ans*k); return 0; }
luogu P3576 [POI2014]MRO-Ant colony