Codeforces Round 108 (C. Berland Regional)

题意:给出数组 u u u和 s s s,对应位置 ( u i , s i ) (u_i,s_i) (ui​,si​)表示该学生在学校 u i u_i ui​,能力为 s i s_i si​,学校按每 k k k ( 1 ≤ k ≤ n ) (1\leq k \leq n) (1≤k≤n)人分组,少于 k k k人不能组队,依次求出按 k k k分,所有学校的参赛队伍最大能力总和。

STL+模拟+前缀和

#include<bits/stdc++.h>
using namespace std;
#define ll long long
//学校编号去重(set)
//按学校编号分组并降序排序,每个学校的学生数量不确定
//想到用vector的begin end
//二维vector,第二个维度不确定,只初始化第一个维度
//按k分组可求排好序的前缀和
//判断按k能分到哪里(长度/k*k)
//对每个学校都计算(1~k),更新累加结果
const int MAX=2e5+5;
int u[MAX];
ll pre[MAX],ans[MAX];
vector<int> v[MAX];
int main(){
    ios_base::sync_with_stdio(false);cin.tie(0),cout.tie(0);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        set<int> s;
        for(int i=1;i<=n;i++){
            v[i].clear();
            cin>>u[i];
            s.insert(u[i]);
        }
        for(int i=1;i<=n;i++){
            int x;
            cin>>x;
            v[u[i]].push_back(x);
        }
        for(int e:s){
            sort(v[e].begin(),v[e].end(),greater<int>());
            int m=v[e].size();//求第二维大小
            for(int i=1;i<=m;i++)
                pre[i]=pre[i-1]+v[e][i-1];//前缀和
            for(int i=1;i<=m;i++)
                ans[i]+=pre[m/i*i];//更新累加结果
        }
        for(int i=1;i<=n;i++)
            cout<<ans[i]<<" ";
        cout<<endl;
        memset(ans,0,sizeof ans);
    }
}

上一篇:application/json IE 兼容问题


下一篇:2021-04-25