結果
問題 | No.563 超高速一人かるた large |
ユーザー |
![]() |
提出日時 | 2017-08-25 23:25:54 |
言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 942 ms / 3,000 ms |
コード長 | 3,300 bytes |
コンパイル時間 | 1,704 ms |
コンパイル使用メモリ | 169,904 KB |
実行使用メモリ | 66,880 KB |
最終ジャッジ日時 | 2024-10-15 16:12:20 |
合計ジャッジ時間 | 8,303 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 18 |
ソースコード
#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <ctime>#include <cassert>#include <string>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <functional>#include <iostream>#include <map>#include <set>#include <cassert>#include <bits/stdc++.h>using namespace std;typedef long long ll;typedef pair<int,int> P;typedef pair<int,P> P1;typedef pair<P,P> P2;#define pu push#define pb push_back#define mp make_pair#define eps 1e-7#define INF 1000#define mod 1000000007#define fi first#define sc second#define rep(i,x) for(int i=0;i<x;i++)#define SORT(x) sort(x.begin(),x.end())#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())int n;string str[2005];int NN,k;int ran[300005];int tmp[300005];int sa[300005];bool compare_sa(int i,int j){if(ran[i] != ran[j]) return ran[i] < ran[j];else{int ri = i+k<=NN ? ran[i+k]: -1;int rj = j+k<=NN ? ran[j+k]: -1;return ri < rj;}}void construct_sa(string S){NN = S.size();for(int i=0;i<=NN;i++){sa[i] = i;ran[i] = i<NN?S[i]:-1;}for(k=1;k<=NN;k*=2){sort(sa,sa+NN+1,compare_sa);tmp[sa[0]] = 0;for(int i=1;i<=NN;i++){tmp[sa[i]] = tmp[sa[i-1]] + compare_sa(sa[i-1],sa[i]);}for(int i=0;i<=NN;i++){ran[i] = tmp[i];}}}int lcp[300005];void construct_lcp(string S){int n = S.size();for(int i=0;i<=n;i++) ran[sa[i]] = i;int h = 0;lcp[0] = 0;for(int i=0;i<n;i++){int j = sa[ran[i]-1];if(h) h--;for(;j+h<n && i+h<n;h++){if(S[j+h] != S[i+h]) break;}lcp[ran[i]-1] = h;}}#define mod 1000000007ll modpow(ll x,ll n){ll res=1;while(n>0){if(n&1) res=res*x%mod;x=x*x%mod;n>>=1;}return res;}ll F[200005],R[200005];void make(){F[0] = 1;for(int i=1;i<200005;i++) F[i] = F[i-1]*i%mod;for(int i=0;i<200005;i++) R[i] = modpow(F[i],mod-2);}ll C(int a,int b){return F[a]*R[b]%mod*R[a-b]%mod;}int ML[2005][2005];int cnt[2005][2005];ll FF[2005][2005];ll ans[2005];string S;int main(){cin >> n;for(int i=0;i<n;i++){cin >> str[i];S += str[i];S += "*";}construct_sa(S);construct_lcp(S);vector<P>RR;int cur = 0;for(int i=0;i<n;i++){RR.pb(mp(ran[cur],i));cur += str[i].size()+1;}sort(RR.begin(),RR.end());for(int i=0;i<RR.size();i++){int val = INF,nxt = RR[i].fi;for(int j=i+1;j<RR.size();j++){while(nxt < RR[j].fi){val = min(val,lcp[nxt++]);}ML[RR[i].sc][RR[j].sc] = ML[RR[j].sc][RR[i].sc] = val;}}make();for(int k=1;k<=n;k++){for(int l=0;l<k;l++){FF[k][l] = C(k,l+1)*F[l]%mod*F[n-l-1]%mod*R[n-k]%mod;}for(int l=k;l<=n;l++){FF[k][l] = 0;}}for(int i=0;i<n;i++){for(int j=0;j<n;j++){if(i==j) continue;cnt[i][ML[i][j]+1]++;}}for(int i=0;i<n;i++){for(int k=1;k<=n;k++){ans[k] += (ll)(str[i].size()+1) * FF[k][0] % mod;ans[k] %= mod;//if(k==3) cout << ans[k] << endl;int L = 0;for(int x=str[i].size()+1;x>=2;x--){L += cnt[i][x];ans[k] -= FF[k][L]; //if(k==3) cout << ans[k] << endl;}}}for(int k=1;k<=n;k++){cout << (ans[k]%mod+mod)%mod << endl;}}