题目链接:https://atcoder.jp/contests/arc117/tasks/arc117_c
Problem Statement
We have NN blocks arranged in a row, where each block is painted blue, white, or red. The color of the ii-th block from the left (1≤i≤N) is represented by a character ci; B
, W
, and R
stand for blue, white, and red, respectively.
From this situation, we will pile up blue, white, and red blocks to make a pyramid with N steps. The following figure shows an example of this:
Here, we place blocks one by one from bottom to top as follows:
- if the two blocks immediately below a position have the same color, we will place there a block of the same color;
- if the two blocks immediately below a position have different colors, we will place there a block of the color different from those two colors.
What will be the color of the block at the top?
Constraints
- NN is an integer satisfying 2≤N≤400000
- Each of c1,c2,…,cN is
B
,W
, orR
.
Input
Input is given from Standard Input in the following format:
N
c1c2⋯⋯cN
Output
If the topmost block will be blue, print B
; if it will be white, print W
; if it will be red, print R
.
一道很好的思维题目,对于最后一行,我们可以算每一个格子对最后答案的“贡献”。令b=0,w=1,r=2 。对于最后一行第一个格子,他的贡献次数为1次,第二个格子贡献次数为C(n-1,1)次,C()为组合数。以此类推(相当于从最上面一行开始走到当前格子有几种走法)。
所以最后把最后一行每个格子的权重乘以次数再对3取模就i可以了。
由于n比较大,我们可以用卢卡斯定理处理。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<map>
#include<set>
#include<queue>
using namespace std;
long long F[10010];
long long mod = 3;
void init(long long p)
{
F[0] = 1;
for (int i = 1; i <= p; i++)
F[i] = F[i - 1] * i % (mod);
}
long long inv(long long a, long long m)
{
if (a == 1)return 1;
return inv(m%a, m)*(m - m / a) % m;
}
long long Lucas(long long n, long long m, long long p)
{
long long ans = 1;
while (n&&m)
{
long long a = n % p;
long long b = m % p;
if (a < b)return 0;
ans = ans * F[a] % p*inv(F[b] * F[a - b] % p, p) % p;
n /= p;
m /= p;
}
return ans;
}
int main()
{
int n;
scanf("%d", &n);//b,w,r=0,1,2
init(3);
char ch[400005];
map<char, int>M;
for (int i = 0; i < n; i++)
{
cin >> ch[i];
}
M['B'] = 0;
M['W'] = 1;
M['R'] = 2;
int ans=0;
int sign;
if (n % 2 == 0)
sign = -1;
else
sign = 1;
for (int i = 0; i < n; i++)
{
int t = Lucas(n - 1, i,3)*M[ch[i]];
t = t * sign;
if (t < 0)
{
int tem = (-t) / 3 + 1;
t = t + 3 * tem;
}
ans += t;
ans = ans % 3;
}
if (ans == 0)
puts("B");
else if (ans == 1)
puts("W");
else
puts("R");
//system("pause");
}