CF 1260-E Tournament 两种实现方法

1.dp做法(官方题解)
CF 1260-E Tournament 两种实现方法_第1张图片
这里就不做解释了
——————————————————————————————

2.找规律
可以根据人数划分出有机会成为第一名,前二强,4强,8强。。。
(当然不贿赂别人)
第1名当然必须是第n个
前二强为 n/2~n
前4强为 n/4~n
前 8 强 n/8~n

根据这个可以判断出friend最多可以到前多少(不贿赂)
之后贿赂的人必须要是可以进入下一级的人
why?

假设friend 的能力是i , n/(a*2)<=i

首先贿赂的人一定在n/(a*2)到n之间,只有这样才能有机会贿赂

然后必须要知道以下:
a个人进入到了前a强,那么按能力值从小到大就必须第1个人前面有至少(n/a)-1个人 第2 个人前面至少2*(n/(a)-1) 个人。。。
如果贿赂的人不在n/a 到 n 之间,那么必定在n/(a2) 到 (n/a)-1 之间,二这里面最多总共有(n/a)-3个人 < 2 * (n/(a2)-1),所以不可能
所以可以获得如下代码:

int n,a[3000000],location=-1;
multiset<int> s;
LL res=0;
int main(){
	cin>>n;
	rb(i,1,n) scanf("%d",&a[i]),location=(a[i]==-1 ? i:location);
	int bound= n,las=n+1;
	while(bound>location){
		rb(i,bound,las-1){
			s.insert(a[i]);
		}
		las=bound;
		res+=*s.begin();
		s.erase(s.begin());
		las=bound;
		bound>>=1;
	}
	cout<<res<<endl;
	return 0;
}

你可能感兴趣的:(题解)