intmain(){ int T; scanf("%d", &T); while (T--) { scanf("%d", &n); set<int> ok, rest; for (int i = 1; i <= n; i++) { scanf("%d", a + i); ok.insert(i); rest.insert(i); } vector<int> ans; int last = 0; while (!ok.empty() && !rest.empty()) { auto it = ok.lower_bound(last); if (it == ok.end()) { it = ok.begin(); } if (!rest.count(*it)) { ok.erase(it); continue; } int x = *it; it = rest.upper_bound(*it); if (it == rest.end()) { it = rest.begin(); } int y = *it; if (__gcd(a[x], a[y]) == 1) { ans.push_back(y); rest.erase(y); last = y + 1; } else { ok.erase(x); } } printf("%d", ans.size()); for (int x: ans) printf(" %d", x); puts(""); } return0; }
namespace acam { staticconstint maxp = 1000000 + 5; staticconstint S = 26; staticconstint Base = 'a'; int sz, ch[maxp][S], fail[maxp], val[maxp], link[maxn]; int tot, tin[maxp], tout[maxp]; vector<int> edge[maxp]; intnode(){ ms(ch[++sz], 0); fail[sz] = val[sz] = 0; return sz; } voidclear(){ sz = 0; node(); for (int i = 0; i < S; i++) ch[0][i] = 1; } intinsert(char* s, int id){ int u = 1; for (int i = 0; s[i]; i++) { int v = s[i] - Base; // ! if (!ch[u][v]) ch[u][v] = node(); u = ch[u][v]; } val[u] = id; return u; } voiddfs(int u){ tin[u] = ++tot; for (int v: edge[u]) { link[v] = val[v] > 0 ? v : link[u]; dfs(v); } tout[u] = tot; } voidbuild(){ queue<int> q; q.push(1); while (!q.empty()) { int t = q.front(); q.pop(); for (int i = 0; i < S; i++) { if (ch[t][i]) { fail[ch[t][i]] = ch[fail[t]][i]; q.push(ch[t][i]); } else { ch[t][i] = ch[fail[t]][i]; } } } for (int i = 2; i <= sz; i++) { edge[fail[i]].push_back(i); } link[1] = -1; dfs(1); } }
structBit { int a[maxn]; voidupdate(int i, int x){ for (; i < maxn; i += i & -i) a[i] += x; } intquery(int i){ int r = 0; for (; i; i -= i & -i) r += a[i]; return r; } intquery(int l, int r){ returnquery(r) - query(l - 1); } } f;
int n, pre[maxn], lnk[maxn]; char buf[maxn];
intmain(){ acam::clear(); scanf("%d", &n); vector<string> allS { "" }; for (int i = 1; i <= n; i++) { scanf("%s", buf); acam::insert(buf, i); allS.emplace_back(buf); } acam::build(); int ans = 0; for (auto& str: allS) { for (int i = 0, u = 1; i < str.length(); i++) { u = acam::ch[u][str[i] - 'a']; pre[i + 1] = u; if (i + 1 < str.length()) { int p = acam::link[u]; lnk[i + 1] = p; } else { int p = acam::link[acam::fail[u]]; lnk[i + 1] = p; } } auto update = [&](int x, int y = 1) { if (x < 1) return ; f.update(acam::tin[x], y); }; auto marked = [&](int x) { return f.query(acam::tin[x], acam::tout[x]); }; vector<int> add; set<int> key; int L = str.length() + 1; for (int i = str.length(); i >= 1; i--) { int x = lnk[i]; if (x == -1) continue; int match = acam::val[x]; if (i - allS[match].length() < L) { L = i - allS[match].length(); key.insert(x); x = acam::fail[x]; } if (x != -1) add.push_back(x); } for (int x: add) update(x, 1); for (int x: key) ans += marked(x) == 0; for (int x: add) update(x, -1); assert(!marked(1)); } printf("%d\n", ans); return0; }