J - Jinxed Betting (推式子,模拟,阅读理解好题)

J - Jinxed Betting

题面:

Julia is betting on a large sporting competition involving matches between pairs of teams. There are no parallel matches and each bettor receives one point for every correct bet they make. Julia had a good streak and is in the lead. Now she worries that her good luck may be turning, and decides to change her strategy.

She collaborates with a betting shop owner who tells her the bets made by everyone else. Whenever Julia makes a bet, she first checks the bets of all bettors with the most points so far (except herself of course) and then chooses the same team as the majority. In the case of a tie, she bets on her favourite of the two teams in the game.

Julia wants to know for how many more matches she is guaranteed to stay in the lead in the worst case (i.e., no matter what bets the others make or what the outcomes of the games are). For this problem we consider Julia to be in the lead if there is no other bettor that has strictly more points than her.

For example, suppose as in Sample Input 1 that Julia initially has three points, and there are two other bettors with three and two points respectively. For the first match, she will make the same bet as the other bettor with three points. If this person bets on the losing team and the other bets on the winning team all players have an equal score of three points. If for the next match the other two persons bet on different teams, Julia places the bet on her favourite, which of course may lose. Thus after two more matches she might lose the lead.

分析:

  • 这篇英语要好好看,对着翻译和同学看了一小时,愣是不知道讲了个寂寞~~~

  • 然后,经大佬指正总算是知道题意,就是讲了个寂寞

    给定序列 A A A,对序列 A A A 进行操作,设最大的数有 a a a 个,每次操作将最大数的 ⌊ a 2 ⌋ \lfloor \frac{a}{2} \rfloor 2a 个,和其它所有数均加 1 1 1 ,问在保证最大数不大于 k e y key key 的前提下,至多操作多少次

    设某一时刻,最大的数 x 1 x_1 x1 a 1 a_1 a1 个,次大数 x 2 x_2 x2 a 2 a_2 a2 个,可推出一个结论: F 1 = ( x 1 − x 2 ) ( l o g 2 a 1 + 1 ) F_1=(x_1-x_2)(log_2a_1+1) F1=(x1x2)(log2a1+1) 轮,次大数全部和最大数一样了,数量变成 a 1 + a 2 a_1+a_2 a1+a2

    还有一个结论:最大数追上 k e y key key ,要经过 F 2 = ( k e y − a 1 ) + ( k e y − a 1 ) / l o g 2 a 1 F_2=(key-a_1)+(key-a_1)/log_2a_1 F2=(keya1)+(keya1)/log2a1

  • 分类讨论:

    • 只剩下一种数(最大数): a n s + = F 2 ans+=F_2 ans+=F2
    • 最大数先追上 k e y key key,即: F 2 < = F 1 F_2<=F_1 F2<=F1 a n s + = F 2 ans+=F_2 ans+=F2
    • 次大数先追上最大数,即: F 2 > F 1 F_2>F_1 F2>F1,就要合并两个数,再进行下一轮, a n s + = F 1 ans+=F_1 ans+=F1
#include <bits/stdc++.h>
#define int long long 
using namespace std;

typedef pair<int,int> P;
const int N=1e5+5;
int p[N];
stack <P> st;
int lg[N];
signed main()
{
	int n,k;
	scanf("%lld%lld",&n,&k);
	for(int i=1;i<n;i++) scanf("%lld",&p[i]);
	sort(p+1,p+n);
	p[n]=-1; // 巨坑,p[i]可以等于0
	int cnt=1,tot=0;
	for(int i=1;i<n;i++)
	{
		if(p[i]==p[i+1]) cnt++;
		else 
		{
			st.push({p[i],cnt});
			cnt=1;
		}
	}
	for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
	int ans=0;
	while(1)
	{
		P u=st.top(); st.pop();
		int x1=u.first, a1=u.second;
		int t1=0,t2=0;
		if(lg[a1]) t2=k-ans-x1+(k-ans-x1)/lg[a1]; 
		if(st.empty()) // 第一类
		{
			ans+=t2;
			break;
		}
		P v=st.top(); st.pop();
		int x2=v.first, a2=v.second;
		t1=(x1-x2)*(lg[a1]+1);
		if(t2<=t1 && t2) // 第二类
		{
			ans+=t2;
			break; 
		}
		ans+=t1; // 第三类
		st.push({x2,a1+a2});
	}
	printf("%lld\n",ans);
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yezzz.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值