QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#638906 | #7008. Rikka with Nice Counting Striking Back | tarjen | AC ✓ | 4794ms | 57116kb | C++20 | 4.7kb | 2024-10-13 17:16:35 | 2024-10-13 17:16:35 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long u64;
struct LongestCommonPrefix {
int n;
vector<int> sa, rk;
vector<vector<int>> st;
LongestCommonPrefix(const string &s) : n(s.size()), sa(n), rk(n) {
int k = 0;
vector<int> q, count;
for (int i = 0; i < n; i += 1) sa[i] = i;
sort(sa.begin(), sa.end(), [&](int i, int j) { return s[i] < s[j]; });
for (int i = 0; i < n; i += 1)
rk[sa[i]] = i and s[sa[i]] == s[sa[i - 1]] ? rk[sa[i - 1]] : k++;
for (int m = 1; m < n; m *= 2) {
q.resize(m);
for (int i = 0; i < m; i += 1) q[i] = n - m + i;
for (int i : sa)
if (i >= m) q.push_back(i - m);
count.assign(k, 0);
for (int i : rk) count[i] += 1;
for (int i = 1; i < k; i += 1) count[i] += count[i - 1];
for (int i = n - 1; i >= 0; i -= 1) sa[count[rk[q[i]]] -= 1] = q[i];
auto cur = rk;
cur.resize(2 * n, -1);
k = 0;
for (int i = 0; i < n; i += 1)
rk[sa[i]] = i and cur[sa[i]] == cur[sa[i - 1]] and
cur[sa[i] + m] == cur[sa[i - 1] + m]
? rk[sa[i - 1]]
: k++;
}
st.emplace_back(n);
for (int i = 0, k = 0; i < n; i += 1) {
if (not rk[i]) continue;
k = max(k - 1, 0);
int j = sa[rk[i] - 1];
while (i + k < n and j + k < n and s[i + k] == s[j + k]) k += 1;
st[0][rk[i]] = k;
}
for (int i = 1; (1 << i) < n; i += 1) {
st.emplace_back(n - (1 << i) + 1);
for (int j = 0; j <= n - (1 << i); j += 1)
st[i][j] = min(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
}
}
int get(int i, int j) {
if (i == j) return n - i;
if (i == n or j == n) return 0;
i = rk[i];
j = rk[j];
if (i > j) swap(i, j);
int k = 64 - __builtin_clzll(u64(j - i)) - 1;
return min(st[k][i + 1], st[k][j - (1 << k) + 1]);
}
};
/*
input 0 base
output [l,r,sa] 1base
*/
pair<vector<tuple<int, int, int>>,LongestCommonPrefix> run(const string &s) {
int n = s.size();
auto r = s;
reverse(r.begin(), r.end());
LongestCommonPrefix lcp(s), lcs(r);
vector<tuple<int, int, int>> runs;
for (bool inv : {false, true}) {
vector<int> lyn(n, n), stack;
for (int i = 0; i < n; i += 1) {
while (not stack.empty()) {
int j = stack.back(), k = lcp.get(i, j);
if (i + k < n and ((s[i + k] > s[j + k]) ^ inv)) break;
lyn[j] = i;
stack.pop_back();
}
stack.push_back(i);
}
for (int i = 0; i < n; i += 1) {
int j = lyn[i], t = j - i, l = i - lcs.get(n - i, n - j),
r = j + lcp.get(i, j);
if (r - l >= 2 * t) runs.emplace_back(l,r-1,t);
}
}
sort(runs.begin(), runs.end());
runs.erase(unique(runs.begin(), runs.end()), runs.end());
return make_pair(runs,lcp);
}
const int N=1e6+10;
const ll p1=31,p2=131;
const ll mod1=1e9+7,mod2=1e9+9;
typedef pair<ll,ll> hs;
const hs p = make_pair(p1,p2);
hs &operator+=(hs &a, hs b) {
a.first=(a.first+b.first)%mod1;
a.second=(a.second+b.second)%mod2;
return a;
}
hs operator+(hs a, hs b) { return a += b; }
hs &operator-=(hs &a, hs b) {
a.first=(a.first-b.first+mod1)%mod1;
a.second=(a.second-b.second+mod2)%mod2;
return a;
}
hs operator-(hs a, hs b) { return a -= b; }
hs &operator*=(hs &a, hs b) {
a.first=(a.first*b.first)%mod1;
a.second=(a.second*b.second)%mod2;
return a;
}
hs operator*(hs a, hs b) { return a *= b; }
struct Hash{
int n;
vector<hs>has1,has2,Pow;
void Hash_init(string &s){
n=(int)s.size();
Pow.resize(n+2);
has1.resize(n+2);
has2.resize(n+2);
Pow[0]=make_pair(1ll,1ll);
for(int i=1;i<=n;i++)Pow[i]=Pow[i-1]*p;
for(int i=1;i<=n;i++)has1[i]=has1[i-1]*p+hs{s[i-1]-'a'+1,s[i-1]-'a'+1};
for(int i=n;i>=1;i--)has2[i]=has2[i+1]*p+hs{s[i-1]-'a'+1,s[i-1]-'a'+1};
}
hs get1(int l,int r){
return has1[r]-has1[l-1]*Pow[r-l+1];
}
hs get2(int l,int r){
return has2[l]-has2[r+1]*Pow[r-l+1];
}
};
ll solve()
{
string s;cin>>s;
auto [runs,lcp]=run(s);
ll ans=0;
int n=s.size();
Hash has;has.Hash_init(s);
for(int i=0;i<n;i++)ans+=n-(i+lcp.st[0][lcp.rk[i]]);
unordered_map<ll,int> ma;
auto insert =[&](hs x){
ma[x.first*(mod2+3)+x.second]=1;
};
for(auto [l,r,p]:runs){
for(int x=l;x<l+p;x++){
for(int y=x+p-1;y+p<=r;y+=p)insert(has.get1(x+1,y+1));
}
}
return ans-(ll)ma.size();
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;cin>>T;while(T--)cout<<solve()<<"\n";
return 0;
}
这程序好像有点Bug,我给组数据试试?
详细
Test #1:
score: 100
Accepted
time: 1ms
memory: 3560kb
input:
6 rikkasuggeststoallthecontestants thisisaproblemdesignedforgrandmasters ifyoudidnotachievethat youdbetterskiptheproblem wishyouahighrank enjoytheexperience
output:
500 679 244 290 132 163
result:
ok 6 lines
Test #2:
score: 0
Accepted
time: 3455ms
memory: 55852kb
input:
1000 mxsslrrxtwwnwlsrxxxbsmtxxwwntsbrwlxnbxunutnlmrrlubturuwmbnobrolwunwurtbnmlumxmwtwrsulruxslsnltsstmmxbsmuonroubrnnmu sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss glggglgg yykkyyyykykykyyyykyykykkkyyyykkyykkkyyykykyykyyykkykky...
output:
6522 1 20 9443 11294 1 8619 26 7898 260905 9048 6 22114 52 20 45 7 39 10 1 28 26 10 47 32 12977 30 13 7473 12 8402 1 8083 16 1 10462 16 9278 1 1 8968 7858 11148 8130 6 8516 12223 9266 8374 26 45 14 10150 9 10175 298758 203677 11522 12 8985 10687 12 1 6613277686 10 10 1 5794 28 1 280529 7874 13 10564...
result:
ok 1000 lines
Test #3:
score: 0
Accepted
time: 4763ms
memory: 57116kb
input:
26 hihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihihhihhihihhihhihihhihihhihhihihhihihhihhihihh...
output:
9523687993 9529757593 9537405289 9539347561 9533035177 9528058105 564250 9522959641 9542382361 9518953705 9519439273 9534977449 9519803449 9535705801 9519560665 9534249097 9527572537 9523687993 9539468953 9532064041 9525873049 9532185433 9541168441 9524901913 9531092905 9518832313
result:
ok 26 lines
Test #4:
score: 0
Accepted
time: 4794ms
memory: 56784kb
input:
26 oohooohoohooohoohooohoohoohooohoohooohoohoohooohoohooohoohoohooohoohooohoohooohoohoohooohoohooohoohoohooohoohooohoohooohoohoohooohoohooohoohoohooohoohooohoohooohoohoohooohoohooohoohoohooohoohooohoohoohooohoohooohoohooohoohoohooohoohooohoohoohooohoohooohoohooohoohoohooohoohooohoohoohooohoohooohooh...
output:
9625902365 9628810517 9622671085 9626467839 9628891299 9626306275 9630668503 9620409189 9618228075 9622428739 9628406607 9625336891 9630426157 9626871749 9620086061 9626144711 9616935563 9617177909 9626790967 9627194877 9626467839 354971 9616370089 9618308857 9617824165 9616773999
result:
ok 26 lines
Test #5:
score: 0
Accepted
time: 3617ms
memory: 56932kb
input:
26 vggvgvggvgvvgvggvgvggvgvvggvgvggvgvvgvggvgvggvgvvgvggvgvvggvgvggvgvvgvggvgvggvgvvgvggvgvggvgvvggvgvggvgvvgvggvgvggvgvvgvggvgvvggvgvggvgvvgvggvgvggvgvvggvgvggvgvvgvggvgvggvgvvgvggvgvggvgvvggvgvggvgvvgvggvgvggvgvvgvggvgvvggvgvggvgvvgvggvgvggvgvvggvgvggvgvvgvggvgvggvgvvgvggvgvvggvgvggvgvvgvggvgvggvg...
output:
13085098340 13073668733 13071665606 13067070197 13077910649 13074964874 13078735466 13070840789 13072726085 13067895014 669720 13065891887 13065302732 13076496677 13068484169 13064242253 13065420563 13063181774 13080502931 13067070197 13072490423 13070015972 13083802199 13064831408 13075671860 13085...
result:
ok 26 lines