题干:

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代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define FF first
#define SS second
#define ll long long
#define pb push_back
#define pm make_pair
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 ;
}