题干:
yah has n strings <s1,⋯,sn>, and he generates a sequence P by two steps:
P=<s1,⋯,sn>
Replace each si with all prefixes of itself.
An example is:
the n strings are < aab,ab >
first, P =< aab,ab >
then, P =< a,aa,aab,a,ab >
There are 26 positive integers d1,⋯,d26 that denote the difficulty to identify lowercase English letter a,b,⋯,z for yah.
The difficulty to identify a string strstr is (i=1∏∣str∣dstri) mod m
Now, yah wants to calculate: for each string si(i=1,⋯,n), the number of strings in P that is prefix of si and more difficult than si.
Input
The first line contains two integers n,mn,m(1≤n≤105,1≤m≤2×105).
The second line contains 26 positive d1,⋯,d26, 0^50≤di≤105.
The following n lines, each line contains a string, the ith lines contains si, the sum of length of all strings is not great than 2×105.
Output
The only line contains n integers, the ith integer denoting the number of strings in P that is prefix of si but more difficult to identify for yah.
题意:
给定n代表n个字符串,m代表模数,再给定26个字母的每个字母的权值d,再定义字符串s的值:前i个字符对应的子串的值dd[i]= dd[i-1]*(d[s[i]]) % m 。
输入n个字符串,求对于每个字符串,大于该字符串 的 值 的 前缀的 个数(值dd[i]= dd[i-1]*(d[s[i]]) % m ),主要求前缀的个数
解题报告:
map暴力搞一搞就能过、、但是要真是比赛场还是老老实实写hash吧、、万一T了呢。
其实也可以字典树,存前缀出现的次数。也不难想。
AC代码:
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
map<string,PII> mp;
int n;
int d[MAX];
ll m;
string s[MAX],tmp;
int main()
{
ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
cin>>n>>m;
for(int i = 0; i<26; i++) cin>>d[i];
for(int i = 1; i<=n; i++) {
cin>>s[i];
tmp = "";
int len = s[i].length();
ll tmpp = 1;
for(int j = 0; j<len; j++) {
tmp += s[i][j];
tmpp *= d[s[i][j]-'a'];
tmpp %= m;
auto it = mp.find(tmp);
if(it == mp.end()) mp[tmp] = pm(tmpp,1);
else mp[tmp].SS ++;
}
}
for(int i = 1; i<=n; i++) {
tmp = "";
int ans = 0;
int tar = mp[s[i]].FF;
int len = s[i].length();
for(int j = 0; j<len; j++) {
tmp += s[i][j];
if(mp[tmp].FF > tar) ans += mp[tmp].SS;
}
cout << ans ;
if(i == n) cout << "\n";
else cout << " ";
//printf("%d%c",ans,i == n ?'\n' :' ');
}
return 0 ;
}