码迷,mamicode.com
首页 > 其他好文 > 详细

[CSP-S模拟测试]:小盆友的游戏(数学 or 找规律)

时间:2019-11-01 20:35:50      阅读:91      评论:0      收藏:0      [点我收藏+]

标签:pac   namespace   The   数据   target   htm   传送门   mod   一个人   

题目传送门(内部题110)


输入格式

  第一行一个整数$N$,表示小盆友的个数。
  第二行$N$个整数$A_i$,如果$A_i=-1$表示$i$目前是自由身,否则$i$是$A_i$的跟班。


输出格式

  一个整数$X$,表示在模$10^9+7$的情况下,期望总猜拳次数。


样例

样例输入1:

2
-1 -1

样例输出1:

1

样例输入2:

3
-1 -1 -1

样例输出2:

3

样例输入3:

4
-1 -1 -1 -1

样例输出3:

7

样例输入4:

5
-1 -1 -1 -1 -1

样例输出4:

15

样例输入5:

3
-1 -1 2

样例输出5:

2

样例输入6:

4
-1 -1 2 2

样例输出6:

4


数据范围与提示

样例$1$解释:

  无论谁输谁赢,一次猜拳后,一个人就成为另外一个人的跟班,那另外一个人则胜出,游戏结束。

数据范围:

  对于$10\%$的数据,满足$n=1$。
  对于$50\%$的数据,满足$n\leqslant 1,000,A_i=-1$。
  对于$100\%$的数据,满足$n\leqslant 100,000$。


题解

样例给这么多,而且还是第一题,一看就是给找规律的;不过为什么出题人不给个类似下面这样的样例?

4
-1 -1 1 2

其实答案就是:

$$ans=2^{(n-1)}-1-(\sum \limits_{i=1}^n2^{(sum[i]-1)}-1)$$

其中$sum[i]$表示$i$的跟班个数。

时间复杂度:$\Theta(n+\log n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
const int mod=1000000007;
int n;
int sum[100001];
long long ans;
long long qpow(long long x,long long y)
{
	long long res=1;
	while(y)
	{
		if(y&1)res=res*x%mod;
		x=x*x%mod;
		y>>=1;
	}
	return res;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++){int x;scanf("%d",&x);if(x!=-1)sum[x]++;}
	ans=qpow(2,n-1)-1;
	for(int i=1;i<=n;i++)
		ans=(ans-qpow(2,sum[i])+1+mod)%mod;
	printf("%lld",ans);
	return 0;
}

rp++

[CSP-S模拟测试]:小盆友的游戏(数学 or 找规律)

标签:pac   namespace   The   数据   target   htm   传送门   mod   一个人   

原文地址:https://www.cnblogs.com/wzc521/p/11779046.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!