BZOJ3872. [Poi2014]Ant colony
阿新 • • 發佈:2020-11-17
Description
There is an entrance to the ant hill in every chamber with only one corridor leading into (or out of) it. At each entry, there are g groups of m1,m2,...,mg ants respectively. These groups will enter the ant hill one after another, each successive group entering once there are no ants inside. Inside the hill, the ants explore it in the following way:Input
The first line of the standard input contains three integers n, g, k (2<=n,g<=1000000, 1<=k<=10^9), separated by single spaces. These specify the number of chambers, the number of ant groups and the number of ants the anteater devours at once. The chambers are numbered from 1 to n. The second line contains g integers m[1],m[2],...,m[g](1<=m[i]<=10^9), separated by single spaces, where m[i] gives the number of ants in the i-th group at every entrance to the ant hill. The n-1 lines that follow describe the corridors within the ant hill; the i-th such line contains two integers a[i],b[i] (1<=a[i],b[i]<=n), separated by a single space, that indicate that the chambers no.a[i] and b[i] are linked by a corridor. The anteater has dug into the corridor that appears first on input. 第一行包含三個整數n,g,k,表示點數、螞蟻群數以及k。 第二行包含g個整數m[1],m[2],...,m[g],表示每群螞蟻中螞蟻的數量。 接下來n-1行每行兩個整數,表示一條邊,食蟻獸埋伏在輸入的第一條邊上。
Output
Your program should print to the standard output a single line containing a single integer: the number of ants eaten by the anteater. 一個整數,即食蟻獸能吃掉的螞蟻的數量。
Sample Input
7 5 33 4 1 9 11
1 2
1 4
4 3
4 5
4 6
6 7
Sample Output
21Hint
Source
題解:沒什麼意思的一道閱讀理解題,考慮到對於每一個節點,若要對答案有貢獻,則蟻群數量在一個區間【l,r】,l,r與當前節點的父節點的度數之積有關,然後雙指標掃兩遍就行了,注意這題要設一個inf。
#include<bits/stdc++.h> using namespace std; const int N=2000005; const long long inf=1000000009; typedef long long ll; typedef pair<ll,int> pli; int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1; ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f; } struct Edg{ int nxt,poi; }e[N*2]; long long a[N],ri[N],b[N],m[N]; int fir[N],l=0,n,k,r1,r2,d[N],sol[N]; void addedge(int u,int v){ l++; e[l].nxt=fir[u]; e[l].poi=v; fir[u]=l; } void dfs(int u,int f){ for (int p=fir[u];p;p=e[p].nxt){ int v=e[p].poi; if (v==f) continue; ri[v]=ri[u]*(d[u]-1); if (ri[v]>inf) ri[v]=inf; dfs(v,u); } } pli ep[N]; int main(){ int n=read(),g=read(),k=read(); for (int i=1;i<=g;i++) m[i]=read(); for (int i=1;i<n;i++){ int x=read(),y=read(); d[x]++; d[y]++; addedge(x,y); addedge(y,x); if (i==1){r1=x; r2=y;} } ri[r1]=ri[r2]=1; dfs(r1,r2); dfs(r2,r1); for (int i=1;i<=n;i++){ a[i]=ri[i]*k; b[i]=(ri[i])*(k+1)-1; if (ri[i]==1) b[i]=a[i]; if (a[i]>inf) a[i]=inf; if (b[i]>inf) b[i]=inf; } int tot=0; for (int i=1;i<=n;i++){ if (d[i]>1) continue; ep[++tot]=make_pair(a[i],i); } sort(m+1,m+1+g); sort(ep+1,ep+1+tot); int l=0; m[g+1]=(inf+2)*k+233; for (int i=1;i<=tot;i++){ while (m[l]<ep[i].first){ l++; } l--; if (l<0) l=0; sol[ep[i].second]-=l; } tot=0; for (int i=1;i<=n;i++){ if (d[i]>1) continue; ep[++tot]=make_pair(b[i],i); } sort(ep+1,ep+1+tot); l=0; for (int i=1;i<=tot;i++){ while (m[l]<=ep[i].first){ l++; } l--; if (l<0) l=0; sol[ep[i].second]+=l; } ll ans=0; for (int i=1;i<=n;i++){ ans+=1ll*k*sol[i]; } printf("%lld\n",ans); return 0; }View Code