逆元(费马小定理)
Madam Hannah Otto, the CEO of Reviver Corp., is fond of palindromes, or words that read the same forwards or backwards. She thinks palindromic brand names are appealing to millennials.
As part of the marketing campaign for the company's new juicer called the Rotator™, Hannah decided to push the marketing team's palindrome-searching skills to a new level with a new challenge.
In this challenge, Hannah provides a string consisting of lowercase English letters. Every day, for days, she would select two integers and , take the substring (the substring of from index to index ), and ask the following question:
Consider all the palindromes that can be constructed from some of the letters from . You can reorder the letters as you need. Some of these palindromes have the maximum length among all these palindromes. How many maximum-length palindromes are there?
For example, if , and , then we have,
Your job as the head of the marketing team is to answer all the queries. Since the answers can be very large, you are only required to find the answer modulo .
Complete the functions initialize
and answerQuery
and return the number of maximum-length palindromes modulo .
Input Format
The first line contains the string .
The second line contains a single integer .
The of the next lines contains two space-separated integers , denoting the and values Anna selected on the day.
Constraints
Here, denotes the length of .
Subtasks
For 30% of the total score:
For 60% of the total score:
Output Format
For each query, print a single line containing a single integer denoting the answer.
Sample Input 0
week 2 1 4 2 3
Sample Output 0
2 1
Explanation 0
On the first day, and . The maximum-length palindromes are "ewe" and "eke".
On the second day, and . The maximum-length palindrome is "ee".
Sample Input 1
abab 1 1 4
Sample Output 1
2
Explanation 1
Here, the maximum-length palindromes are "abba" and "baab".
Sponsor
题意:给你一个字符串;有n此询问,每次询问给你一个区间,l-r;问你在这个区间中(字母可以任意匹配)有多少种最长回文子串;首先因为是回文串所以左右字符必须相等;求在这个区间中满足条件字符的个数(num>=2);求得总的对数sum(因为要分在两端只确定一边就可以);求出之后求组合数A(sum)/(A[num[i]]的阶乘)因为会出现相同的字母,即可以理解为在总对数sum上找不同的字母数进行排序。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+100;
const ll mod=1e9+7;
ll mp[maxn][333];
ll num[maxn];
ll res[maxn];
ll qpow(ll a,ll b)
{
if(b<0) return 0;
ll ans=1;
a%=mod;
while(b)
{
if(b&1) ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
ll inv(ll a)
{
return qpow(a,mod-2);
}
void init()
{
res[0]=1;
for(int i=1;i<=maxn;i++)
{
res[i]=(res[i-1]*(ll)i)%mod;
}
}
int main()
{
string s;
cin>>s;
init();
int len=s.size();
for(int i=1;i<=len;i++)
{
for(int j=0;j<26;j++)
{
mp[i][j]=mp[i-1][j];
}
mp[i][s[i-1]-'a']+=1;
}
int t;
cin>>t;
while(t--)
{
int l,r;
scanf("%d%d",&l,&r);
ll ans=0;
ll tot=0;
for(int i=0;i<26;i++)
{
int now=mp[r][i]-mp[l-1][i];
ans+=now/2;
tot+=now%2;
}
ans=res[ans];
// cout<<ans<<" "<<res[ans]<<endl;
for(int i=0;i<26;i++)
{
int now=mp[r][i]-mp[l-1][i];
if(now/2>0)
{
ans*=inv(res[now/2]);
ans%=mod;
}
}
if(tot>0) ans=(ans*tot)%mod;
if(ans<0) ans+=mod;
if(ans>0) cout<<ans<<endl;
else cout<<tot<<endl;
}
return 0;
}
上一篇: 模拟DNF放技能的蓝耗问题(P2006题题解,Java语言描述)
下一篇: 数论逆元