CodeForces 520C DNA Alignment

C. DNA Alignment
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Vasya became interested in bioinformatics. He's going to write an article about similar cyclic DNA sequences, so he invented a new method for determining the similarity of cyclic sequences.

Let's assume that strings s and t have the same length n, then the function h(s, t) is defined as the number of positions in which the respective symbols of s and t are the same. Function h(s, t) can be used to define the function of Vasya distance ρ(s, t)

where   is obtained from string  s, by applying left circular shift  i times. For example, 
ρ("AGC", "CGT") = 
h("AGC", "CGT") + h("AGC", "GTC") + h("AGC", "TCG") + 
h("GCA", "CGT") + h("GCA", "GTC") + h("GCA", "TCG") + 
h("CAG", "CGT") + h("CAG", "GTC") + h("CAG", "TCG") = 
1 + 1 + 0 + 0 + 1 + 1 + 1 + 0 + 1 = 6

Vasya found a string s of length n on the Internet. Now he wants to count how many strings t there are such that the Vasya distance from the string s attains maximum possible value. Formally speaking, t must satisfy the equation: .

Vasya could not try all possible strings to find an answer, so he needs your help. As the answer may be very large, count the number of such strings modulo 109 + 7.

Input

The first line of the input contains a single integer n (1 ≤ n ≤ 105).

The second line of the input contains a single string of length n, consisting of characters "ACGT".

Output

Print a single number — the answer modulo 109 + 7.

Sample test(s)
input
1
C
output
1
input
2
AG
output
4
input
3
TTT
output
1
Note

Please note that if for two distinct strings t1 and t2 values ρ(s, t1) и ρ(s, t2) are maximum among all possible t, then both strings must be taken into account in the answer even if one of them can be obtained by a circular shift of another one.

In the first sample, there is ρ("C", "C") = 1, for the remaining strings t of length 1 the value of ρ(s, t) is 0.

In the second sample, ρ("AG", "AG") = ρ("AG", "GA") = ρ("AG", "AA") = ρ("AG", "GG") = 4.

In the third sample, ρ("TTT", "TTT") = 27


唔。。。这道题是周四下午练习的时候做的

当时看到数据范围在10^5以内也没当一回事


直到最后发现这是字符串的长度范围(⊙o⊙)…


这要是暴利得多久啊,当时还闲得写了个暴力

10^1数量级的数据一分钟都跑不完,更别说是10^5了。。。


That's a sad story....

无奈只能看题解


题目大意就是给定字符串s,求满足函数ρ(s, t)取到最大值的字符串t的个数

s和t的长度相等,且其包含的字符都在集合S = { 'A', 'C', 'G', 'T' }中


首先要知道在什么样的情况下函数ρ(s, t)取得最大值

因为数据范围很大,我们不可能去一一验证

因此只能先分析函数在什么情况下取得最大值,再根据结论构造字符串t


可以看到函数ρ(s, t)中有两个求和符号

很容易推断出ρ(s, t)的值就等于第二个Sigma求出的和值乘以n

因为无论s向左循环移动几次,第二个Sigma求出的和值始终不变


因此我们只需考虑shift(s, i)中i = 0的情况时即可,初始化ρ(s, t) = 0

考虑t中的第一个字符ch1,通过分别0,1,2,3...n-1次向左循环移动,那么ρ(s, t) += G(ch1) (G(ch1)为s中和ch1相同的字符的个数)

类似地,考虑第二个字符,ρ(s, t) += G(ch2)

...

最后ρ(s, t) *= n


即    ρ(s, t) = (G(ch1)+G(ch2)+G(ch3)+G(ch4)+...+G(chn))*n


由上述分析可知,ρ(s, t)的值与字符串t中各字符的位置无关,仅与其个数有关

那么对于任意一个字符chi, G(chi)都取得最大值时,ρ(s, t)必达到最大值


假设s中个数最多的字符为ch,那么根据上述可知,t中所有字符都等于ch时ρ(s, t)取得最大值,而这样的t只有一个

那么样例2中的4又是怎么求出来的哪╮(╯▽╰)╭


可以发现,这样的ch可能不止一个,设满足条件的ch有m个,那么对于每个位置都有m个选择(因为无论选择哪个,G(chi))都是相等的,都可以取得最大值)

即所求答案为 m^n


考虑到到现在还没写过快速幂,这道题正好用一下


代码如下:


#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<cctype>
#define modulus (1000000000+7)
using namespace std;

long long quickpow(long long x, long long b) {
  long long ret = 1;
  
  while (b) {
    if (b & 1) ret = ret*x%modulus;
    b >>= 1;
    x = x*x%modulus;
  }
  
  return ret;
}

int main() {
  long long n; string s;
  cin >> n >> s;
  
  int vis[4] = {0};
  for (int i = 0; i < (int)s.length(); i++) {
    switch (s[i]) {
        case 'A': { vis[0]++; break; }
        case 'G': { vis[1]++; break; }
        case 'C': { vis[2]++; break; }
        case 'T': { vis[3]++; break; }
        default : break;
    }
  }
  
  sort(vis,vis+4);
  
  long long cnt = 0;
  for (int i = 3; i >= 0; i--)
    if (vis[i] == vis[3]) cnt++;
  
  //cout << cnt << " " << n << endl;
  cout << quickpow(cnt, n) << endl;

  return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值