Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdio>
- #include <algorithm>
- #include <vector>
- #include <bitset>
- #include <set>
- #define task "eticket"
- using namespace std;
- using ld = long double;
- using ll = long long;
- const int N = 2e3 + 5;
- const ll base = 101;
- const ll mod = 1e9 + 3;
- struct Trie {
- set<ll> s[N];
- void Update(const string &p) {
- ll v = 0;
- for(auto i : p)
- v = (v * base + (i == '.' ? 28 : (i - 'a' + 1))) % mod;
- s[p.size()].insert(v);
- }
- int Check(int x, ll y){
- auto j = s[x].find(y);
- return (j != s[x].end());
- }
- } pref;
- int n, m, nxt[N * 2];
- bitset<N> f[N];
- ll Pow[N], a[N * 2];
- void Prepare(){
- Pow[0] = 1;
- for(int i = 1; i < N; ++i) Pow[i] = Pow[i - 1] * base % mod;
- }
- ll Get(int x, int y){
- return ((a[y] - a[x - 1] * Pow[y - x + 1]) % mod + mod) % mod;
- }
- void Get(const string &s, bitset<N> &f) {
- for(int i = 1; i <= m * 2; ++i)
- a[i] = (a[i - 1] * base + (s[i] == '.' ? 28 : (s[i] - 'a' + 1))) % mod;
- for(int i = m * 2; i; --i)
- nxt[i] = ( (s[i] >= 'a' && s[i] <= 'z') && (i == m * 2 || s[i + 1] > 'z' || s[i + 1] < 'a') )
- ? i : nxt[i + 1];
- int cnt(0), res(0), last(1), i(1);
- while(i < m * 2) {
- /// Update for last
- if((s[i - 1] > 'z' || s[i - 1] < 'a') && (s[i] >= 'a' && s[i] <= 'z')){
- ++cnt;
- last = i;
- }
- if(s[i] > 'z' || s[i] < 'a') last = i;
- last = max(last, i - m + 1);
- if(s[i] >= 'a' && s[i] <= 'z')
- res += pref.Check(i - last + 1, Get(last, i)) - pref.Check(i - last, Get(last, i - 1));
- ///Update for first
- if(i >= m && (s[i - m + 1] < 'a' || s[i - m + 1] > 'z'))
- cnt -= (s[i - m] >= 'a' && s[i - m] <= 'z');
- if(i >= m && s[i - m] >= 'a' && s[i - m] <= 'z') {
- int nex = min(nxt[i - m], i);
- res += pref.Check(nex - (i - m + 1) + 1, Get(i - m + 1, nex)) - pref.Check(nex - (i - m) + 1, Get(i - m, nex));
- }
- if(i >= m) f[i - m] = (res == cnt);
- //cout << i << " --- " << res << " " << cnt << "\n";
- ++i;
- }
- }
- void Read() {
- cin >> m;
- for(int i = 1; i <= m; ++i){
- string s;
- cin >> s;
- pref.Update(s);
- }
- cin >> n;
- for(int i = 1; i <= n; ++i) {
- string s;
- cin >> s;
- m = s.size();
- s = " " + s + s;
- //cout << i << ": " << s << "\n";
- Get(s, f[i]);
- //cout << i << ": " << f[i] << "\n";
- }
- }
- void Solve() {
- for(int i = 0; i < m; ++i) f[0][i] = 1;
- for(int i = 1; i <= n; ++i)
- f[0] &= f[i];
- cout << f[0].count() << '\n';
- for(int i = 0; i < m; ++i)
- if(f[0][i]) cout << i << " ";
- }
- int32_t main(){
- ios::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- if(fopen(task".INP", "r")){
- freopen(task".INP", "r", stdin);
- freopen(task".OUT", "w", stdout);
- }
- Prepare();
- Read();
- Solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement