[CF1519C]Berland Regional

Posted Tan_tan_tann

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF1519C]Berland Regional相关的知识,希望对你有一定的参考价值。

Berland Regional

题解

首先,每个大学本身对答案的贡献是独立的,所以我们可以单独对答案进行计算。
由于当参赛人数大于大学的总人数时,该大学不会对这些答案产生任何贡献,所以对于大学 u i u_{i} ui,我们只需要计算 [ 1 , ∣ U i ∣ ] [1,|U_{i}|] [1,Ui]的答案。
计算单个大学的答案时,我们可以先将该大学的人按 s s s排序,对于 i i i,我们会让前 n − n % i n-n\\%i nn%i个人参加队伍,所以也就是 n − n % i n-n\\%i nn%i的前缀和。

对于每个大学都计算一次它对答案产生的贡献,总时间复杂度 O ( ∑ i = 1 n ∣ U i ∣ l o g   ∣ U i ∣ ) = O ( n ) O\\left(\\sum_{i=1}^{n}|U_{i}|log\\,|U_{i}|\\right)=O\\left(n\\right) O(i=1nUilogUi)=O(n)

然后是另外一种SYDevil巨佬提供的一种 O ( n n ) O\\left(n\\sqrt{n}\\right) O(nn )的做法,准确说就是当你忘记了对于每个大学只统计到 ∣ S ∣ |S| S时,可以将这些大学按人数分块,小块就统计到 n \\sqrt{n} n ,大块统计到 n n n,其实也没什么特别的

源码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
#define lowbit(x) (x&-x)
#define reg register
typedef long long LL;
typedef unsigned long long uLL;
typedef unsigned int uint;
const int INF=0x7f7f7f7f;
const int jzm=233;
const int mo=998244353;
const double Pi=acos(-1.0);
typedef pair<int,int> pii;
const double PI=acos(-1.0);
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
int t,n,ui[MAXN],len[MAXN];LL ans[MAXN];
vector<LL>uni[MAXN];
bool cmp(int x,int y){return x>y;}
int main(){
	read(t);
	while(t--){
		read(n);for(int i=1;i<=n;i++)read(ui[i]);
		for(int i=1,x;i<=n;i++)read(x),uni[ui[i]].push_back(1ll*x);
		for(int i=1;i<=n;i++){
			sort(uni[i].begin(),uni[i].end(),cmp);
			len[i]=uni[i].size();for(int j=1;j<len[i];j++)uni[i][j]+=uni[i][j-1];
			for(int j=1;j<=len[i];j++){
				int tmp=len[i]-len[i]%j;
				ans[j]+=uni[i][tmp-1];
			}
		}
		for(int i=1;i<=n;i++)printf("%lld ",ans[i]),ans[i]=0;puts("");
		for(int i=1;i<=n;i++)uni[i].clear();
	}
	return 0;
}

分块

int s,fr[200005],B;
vector<ll>a[200005];
vector<int>h,p;
int main(){
	for(int T=read;T--;){
		s=read;B=sqrt(s)+1;
		for(int i=1;i<=s;++i)
			a[i].clear();
		h.clear();p.clear();
		for(int i=1;i<=s;++i)fr[i]=read;
		for(int i=1;i<=s;++i)a[fr[i]].push_back(read);
		for(int i=1;i<=s;++i){
			if(a[i].size()>B)h.push_back(i);
			else p.push_back(i);
			sort(a[i].begin(),a[i].end());
			reverse(a[i].begin(),a[i].end());
			for(int j=1;j<a[i].size();++j)
				a[i][j]+=a[i][j-1];
		}
		for(int i=1;i<=s;++i){
			ll t=0;
			for(int j=0;j<h.size();++j)
				t+=a[h[j]].size()<i?0:a[h[j]][a[h[j]].size()/i*i-1];
			if(i<=B)
				for(int j=0;j<p.size();++j)
					t+=a[p[j]].size()<i?0:a[p[j]][a[p[j]].size()/i*i-1];
			printf("%lld ",t);
		}putchar('\\n');
	}
	return 0;
}

谢谢!!!

以上是关于[CF1519C]Berland Regional的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round 108 (C. Berland Regional)

Educational Codeforces Round 108 (Rated for Div. 2)-C. Berland Regional-题解

Educational Codeforces Round 108 (Rated for Div. 2) C. Berland Regional(计算复杂度,暴力)

cf723d Lakes in Berland

CF723D Lakes in Berland

题解 CF1359A Berland Poker