题意:给出数组 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);
}
}