蘋果(apple)
【題目背景】
儘管題目名是蘋果,可是此題和蘋果沒有任何關係。
這是爲何呢?
【題目描述】
考慮一個樹形結構的信號傳遞網絡,初始存在一個信號源點,記其標號爲 0。
樹上有兩種節點,一種爲信號中繼點,用來接收父親節點的信號並分發給它的兒子
們。另外一種爲信號接收點,僅能接收父親節點的信號但不能向下傳遞。
對於一箇中繼點 i ,它能最多將信號分發給 ai 個兒子。對於一個接收點 i,它能生
效僅當它與初始源點間的中繼點個數不超過 bi。
對於 bi = 0 的接收點,只能直接鏈接在源點上。源點能夠視做一種特殊的中繼點,
它僅能將信號分發給 1 個兒子。
如今給出 n 箇中繼點和 m 個接收點,小 Z 想知道最多能夠使多少個接收點接受到
信號。
注意你不. 一. 定. 須要使用全部 n + m 個節點。
【輸入格式】
從文件 apple.in 中讀入數據。
輸入的第一行包含兩個正整數 n, m,保證 1 ≤ n, m ≤ 2 · 105,含義如上所述。
輸入的第二行包含 n 個正整數 a1, a2, ..., an,表示 n 箇中繼點。2 ≤ ai ≤ 2 · 105
輸入的第三行包含 m 個正整數 b1, b2, ..., bm,表示 m 個接收點。0 ≤ bi ≤ 2 · 105
【輸出格式】
輸出到文件 apple.out 中。
輸出一行一個正整數,表示最多能夠使多少個接收點接受到信號。
【樣例 1 輸入】
3 6
4 2 2
1 2 3 2 1 1
【樣例 1 輸出】
5
【樣例 2】
見選手目錄下的 apple/apple2.in 與 apple/apple2.ans。
【子任務】
測試點 n m 特殊性質
1 ≤ 3 ≤ 3 無
2 ≤ 10 ≤ 10 無
3 ≤ 20 ≤ 20 無
4 ≤ 20 ≤ 20 bi = i
5 ≤ 200000 ≤ 200000 bi 互不相同
6 ≤ 200000 ≤ 200000 ai = 2
7 ≤ 50000 ≤ 50000 無
8 ≤ 200000 ≤ 200000 無
9 ≤ 200000 ≤ 200000 無
10 ≤ 200000 ≤ 200000 無ios
題解見註釋網絡
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> using namespace std; const int maxn = 2 * 100000 + 10 ; int n,m,a[maxn],b[maxn],ans,now[maxn]; bool cmp(int x,int y){return x>y;} //貪心策略 先放不得不放的接收器 ,在選擇分發能力強的中繼器 bool judge(int x) { memset(now,0,sizeof(now)); int top(0),flor(1);now[flor]=1; for(;;){ while(x && now[flor] && b[x]<flor) x--,now[flor]--;//若是還有剩餘位置,且還有接收七器 if(!x) return true;//若是全部接收器都用了,二分的答案可行; if(x && !now[flor]) return false; //若是還有剩的接收器,且沒有剩餘位置了,不可行 while(now[flor] && top<n)//統計這層的位置放入中繼器,統計下層位置 now[flor+1]+=a[++top],now[flor]--; now[flor+1]+=now[flor];//下層位置加上這層還還剩的位置 flor++; } } int main() { freopen("apple.in","r",stdin); freopen("apple.out","w",stdout); cin>>n>>m; for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=m;i++) scanf("%d",&b[i]); sort(a+1,a+1+n,cmp);//從大到小排序 ,貪心得想,二分選的接收器可大的來; sort(b+1,b+m+1,cmp); int l=1,r=m; while(l<r) { int mid=(l+r)>>1; if(judge(mid)) l=mid+1,ans=mid; else r=mid; } cout<<ans<<endl; return 0; }