QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#287151#7008. Rikka with Nice Counting Striking Backucup-team1209AC ✓5005ms94692kbC++204.4kb2023-12-19 20:10:052023-12-19 20:10:05

Judging History

你现在查看的是最新测评结果

  • [2023-12-19 20:10:05]
  • 评测
  • 测评结果:AC
  • 用时:5005ms
  • 内存:94692kb
  • [2023-12-19 20:10:05]
  • 提交

answer

#include <bits/stdc++.h>
#define cs const
#define pb push_back
using namespace std;
using pi = pair <int, int> ;
using ll = long long ;
using i128 = __int128;
using u128 = __uint128_t;
cs int N = 4e5 + 5, M = 105; 

void cmx(ll & x , ll y) {
    if(x < y) x = y; 
}

int T, n; 
char S[N];
namespace sam {
int ch[N][26], lk[N], len[N], nd = 1, las = 1; 
void init() {
    for(int i = 0; i <= nd; i++) {
        memset(ch[i], 0, 104);
        lk[i] = len[i] = 0; 
    }
    nd = las = 1; 
}
void extend(int c) {
    int x = ++ nd , p = las; las = x; 
    len[x] = len[p] + 1; 
    for(; p && !ch[p][c]; p = lk[p]) ch[p][c] = x; 
    if(!p) return lk[x] = 1, void();
    int q = ch[p][c];
    if(len[q] == len[p] + 1) 
        return lk[x] = q, void();
    int cl = ++ nd; 
    len[cl] = len[p] + 1; 
    memcpy(ch[cl], ch[q], 104);
    lk[cl] = lk[q], lk[q] = lk[x] = cl;
    for(; p && ch[p][c] == q; p = lk[p]) ch[p][c] = cl; 
}
}

struct run {
    int l, r, p;
} ;
vector <run> runs; 

cs ll mod = 995053212556338707, B = 223; 

ll ha[N], pw[N];

ll add(ll a, ll b) {
    return a + b >= mod ? a + b - mod : a + b; 
}
ll dec(ll a, ll b) {
    return a - b < 0 ? a - b + mod : a - b; 
}
ll mul(ll a, ll b) {
    return (__int128_t) a * b % mod; 
}

ll has(int l, int r) {
    if(l > r) return 0;
    return (ha[r] + u128(mod - ha[l - 1]) * pw[r - l + 1]) % mod;
}
i128 has_raw(int l, int r) {
    if(l > r) return 0;
    return ha[r] - (i128) ha[l - 1] * pw[r - l + 1];
}


bool iskmod(i128 x) {
	constexpr i128 mul = []() {
		i128 res = 0;
		for(char c : "93809386772914624520890844190221243419") if(c) {
			res = res * 10 + (c - 48);
		}
		return res;
	}();
	static const ll lim = 2e18;
	x *= mul;
	return -lim < x && x < lim;
}
int lcp(int x, int y) {
    int l = 0, r = min(n - x + 1, n - y + 1);
    while(l < r) {
        int mid = (l + r + 1) >> 1; 
		i128 T = has_raw(x, x + mid - 1) - has_raw(y, y + mid - 1);
        if(iskmod(T)) l = mid; 
        else r = mid - 1; 
    } return l;
}
int lcs(int x, int y) {
    int l = 0, r = min(x, y) + 1; 
    while(l < r) {
        int mid = (l + r + 1) >> 1; 
		const i128 T = has_raw(x - mid + 1, x) - has_raw(y - mid + 1, y);
        if(iskmod(T)) l = mid; 
        else r = mid - 1;
    } return l;
}

bool cmp(int x, int y) {
    int l = lcp(x, y);
    if(x + l > n) return true; 
    if(y + l > n) return false; 
    return S[x + l] < S[y + l];
}

set <pi> ex; 

void ins(int l, int r) {
    // cout << "ins " << l << ' ' << r << endl;
    int p = r - l;
    int l1 = lcp(l, r);
    int l2 = lcs(l - 1, r - 1);
    int L = l - l2, R = r + l1 - 1; 
    // cout << L <<' ' << R << ' ' << p << endl;
    if(R - L + 1 >= 2 * p) {
        auto iter = ex.lower_bound(pi(L, R));
        if(iter != ex.end() && *iter == pi(L, R)) return ;
        
        ex.emplace_hint(iter, pi(L, R));
        runs.pb((run){L, R, p}); // , cout << "RUNS " << L << ' ' << R << " " << p << endl;
    }
}

void Run(int o) {
    static int s[N];
    int top = 0; s[++ top] = n + 1; 
    for(int i = n;i; i--) {
        while(top > 1 && cmp(i, s[top]) == o) -- top;
        ins(i, s[top]); s[++ top] = i; 
    }
}

void Main() {
    scanf("%s", S + 1);
    n = strlen(S + 1);
    ll ans = 0; 
    sam :: init();
    for(int i = 1; i <= n; i++) {
        sam :: extend(S[i] - 'a');
        int x = sam :: las; 
        ans += sam :: len[x] - sam :: len[sam :: lk[x]];
    }
    // cout << ans << '\n';
    pw[0] = 1; 
    for(int i = 1; i <= n; i++)
        pw[i] = mul(pw[i - 1], B);
    for(int i = 1; i <= n; i++)
        ha[i] = add(mul(ha[i - 1], B), S[i] - 'a' + 1); 
    runs.clear();
    ex.clear();
    Run(0);
    Run(1);
    unordered_map <ll, int> mp(n * 15); 
    for(auto [l, r, p] : runs) {
        // cout << l <<' ' << r << ' ' <<p << endl;
        for(int i = 0; i < p; i++) {
            int t = (r - l + 1 - i) / p - 1; 
            if(t) {
                ll h = has(l + i, l + i + p - 1);
                // cout << "FF " << h << ' ' << l + i << ' ' << l + i + p - 1 << ' ' << t << endl;
                int & v = mp[h];
                if(t > v) v = t;
            } else  break;

        }
    }
    for(auto [x, y] : mp)  ans -= y; 
    cout << ans << '\n';
}

int main() {
    #ifdef zqj
    freopen("$.in","r",stdin);
    #endif
    cin >> T; 
    while(T--) {
        Main();
    }
    return 0; 
}

这程序好像有点Bug,我给组数据试试?

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 9792kb

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: 3786ms
memory: 94692kb

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: 5005ms
memory: 87968kb

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: 4953ms
memory: 86764kb

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: 4684ms
memory: 86452kb

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