CF 1260-E Tournament 两种实现方法

1.dp做法(官方题解)
在这里插入图片描述
这里就不做解释了
——————————————————————————————

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) 也就是最多到前a * 2强

首先贿赂的人一定在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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值