CF 1978 D. Elections (*1600) 思維

Showball發表於2024-06-21

CF 1978 D. Elections (*1600) 思維

題目連結

題意

\(n\) 個人進行選舉,第 \(i\) 個人有 \(a_i\) 個粉絲投票給他,另外有 \(c\) 個人沒想好投給誰。他們會投給編號最小的人。投票最多的人將贏得選舉(相同票數,編號選的人獲勝)。現在你可以將一些候選人排除在外,這些人的粉絲也會投給編號最小的人。考慮每個人如果想要贏得選舉,至少需要排除多少個候選人。

思路

最初,\(c\) 票會給 \(1\) 號,然後我們統計一下最大值,顯然最大值對應的答案是 \(0\)。對於其他值,我們需要操作,注意到,每次拿出去的選票只能給編號最小的人,所以對於選手 \(i\) ,我們至少要把前 \(i-1\) 個候選人都排除在外。並將所有的選票加到 選手 \(i\) 上,此時,我們只用判斷我們是否是剩餘的候選人裡票數最多的即可。那麼我們倒著列舉,維護字尾最大值即可。如果當前選票小於字尾最大值,那麼只需要把最大值拿出來加到選手 \(i\) 上即可。

程式碼

#include<bits/stdc++.h>

using namespace std;

#define ff first
#define ss second
#define pb push_back
#define all(u) u.begin(), u.end()
#define endl '\n'
#define debug(x) cout<<#x<<":"<<x<<endl;

typedef pair<int, int> PII;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 10, M = 105;
const int mod = 1e9 + 7;
const int cases = 1;

void Showball(){
   int n,c;
   cin>>n>>c;
   vector<int> a(n+1);
   vector<LL> s(n+1);
   for(int i=1;i<=n;i++) cin>>a[i];
   int maxn=a[1]+c,idx=1;
   s[1]=a[1];
   for(int i=2;i<=n;i++){
      if(a[i]>maxn){
         maxn=a[i];
         idx=i;
      }
      s[i]=s[i-1]+a[i];
   }
   vector<int> ans(n+1);
   if(idx!=n) ans[n]=n-1; 
   maxn=a[n];
   for(int i=n-1;i>=1;i--){
      if(i==idx) {maxn=max(maxn,a[i]);continue;}
      LL cur=s[i]+c;
      if(cur>=maxn) ans[i]=i-1;
      else ans[i]=i;
      maxn=max(maxn,a[i]);
   }
   for(int i=1;i<=n;i++) cout<<ans[i]<<" \n"[i==n];
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int T=1;
    if(cases) cin>>T;
    while(T--)
    Showball();
    return 0;
}                 

相關文章