Balala Power!
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 4124 Accepted Submission(s): 1004
Problem Description
Talented Mr.Tang has n
strings consisting of only lower case characters. He wants to charge
them with Balala Power (he could change each character ranged from a to z into each number ranged from 0 to 25,
but each two different characters should not be changed into the same
number) so that he could calculate the sum of these strings as integers
in base 26 hilariously.
Mr.Tang
wants you to maximize the summation. Notice that no string in this
problem could have leading zeros except for string "0". It is guaranteed
that at least one character does not appear at the beginning of any
string.
The summation may be quite large, so you should output it in modulo 109+7.
Input
The input contains multiple test cases.
For each test case, the first line contains one positive integers n, the number of strings. (1≤n≤100000)
Each of the nextlines contains a string si consisting of only lower case letters. (1≤|si|≤100000,∑|si|≤106)
For each test case, the first line contains one positive integers n, the number of strings. (1≤n≤100000)
Each of the nextlines contains a string si consisting of only lower case letters. (1≤|si|≤100000,∑|si|≤106)
Output
For each test case, output "Case #x: y" in one line (without quotes), where x indicates the case number starting from 1 and y denotes the answer of corresponding case.
Sample Input
1
a
2
aa
bb
3
a
ba
abc
Sample Output
Case #1: 25
Case #2: 1323
Case #3: 18221
Source
题意:给出一些字符串,由小写字母构成,用26(0-25)进制的数代替字母,不同字母不能相同。求转化后的26进制数最大为多少,结果对1e9+7取模。长度大
于1的串结果不能有前导0,除了单个字符.
【思路】:统计每个字符所在位,和其中的个数,以a字符为例。统计结果为
a[0]26^0+a[1]26^1+a[2]x2+.....+a[n-1]26^(n-1),其中a[i]代表a在第i位出现的次数
转化使得a[i]<26,变成x[0]26^0+x[1]26^1+...+x[n-1]26^(n-1)+x[n]26^(n)+...,
每个字符如此操作,谁取得最高位,这个字符就为25,第二高位为24,......,
排个序就可以了。如果出现前导0,从排序好的序列,从前往后找到可以为0的第一个字符,因为能作为0,它的x[i]26^(i)要越小,结果越大
于1的串结果不能有前导0,除了单个字符.
【思路】:统计每个字符所在位,和其中的个数,以a字符为例。统计结果为
a[0]26^0+a[1]26^1+a[2]x2+.....+a[n-1]26^(n-1),其中a[i]代表a在第i位出现的次数
转化使得a[i]<26,变成x[0]26^0+x[1]26^1+...+x[n-1]26^(n-1)+x[n]26^(n)+...,
每个字符如此操作,谁取得最高位,这个字符就为25,第二高位为24,......,
排个序就可以了。如果出现前导0,从排序好的序列,从前往后找到可以为0的第一个字符,因为能作为0,它的x[i]26^(i)要越小,结果越大
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<string.h>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<cmath>
typedef long long ll;
typedef unsigned long long LL;
using namespace std;
const double PI=acos(-1.0);
const double eps=0.0000000001;
const int N=+;
const ll mod=1e9+;
ll num[][N];
ll sum[N];
ll val[N];
int vis[N];
int a[N];
int t;
void init(){
val[]=;
for(int i=;i<=N;i++){
val[i]=val[i-]*%mod;
}
}
bool cmp(int a,int b){
for(int i=t-;i>=;i--){
if(num[a][i]!=num[b][i])
return num[a][i]<num[b][i];
}
}
int main(){
int n;
int tt=;
init();
string s;
while(scanf("%d",&n)!=EOF){
t=;
memset(vis,,sizeof(vis));
memset(num,,sizeof(num));
memset(sum,,sizeof(sum));
for(int i=;i<=n;i++){
cin>>s;
int len=s.size();
if(len>){
vis[s[]-'a']=;
}
for(int j=;j<len;j++){
num[s[j]-'a'][len-j]++;
sum[s[j]-'a']+=val[len-j];
sum[s[j]-'a']%=mod;
}
t=max(t,len);
}
for(int i=;i<;i++){
for(int j=;j<=t;j++){
num[i][j+]+=num[i][j]/;
num[i][j]%=;
}
t++;
while(num[i][t]){
num[i][t+]+=num[i][t]/;
num[i][t++]%=;
}
a[i]=i; }
sort(a,a+,cmp);
int flag;
for(int i=;i<;i++){
if(vis[a[i]]==){
flag=a[i];
break;
}
}
ll ans=;
int x=;
for(int i=;i>=;i--){
if(a[i]!=flag){
ans=ans+((x--)*sum[a[i]]%mod);
ans=ans%mod;
}
}
printf("Case #%d: %d\n",tt++,ans);
}
}