QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#141738#2135. How Many Strings Are LessGamal74#WA 25ms27052kbC++207.2kb2023-08-17 23:04:322023-08-17 23:04:35

Judging History

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

  • [2023-08-17 23:04:35]
  • 评测
  • 测评结果:WA
  • 用时:25ms
  • 内存:27052kb
  • [2023-08-17 23:04:32]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;

#define fi first
#define se second
#define pp push_back
#define all(x) (x).begin(), (x).end()
#define Ones(n) __builtin_popcount(n)
#define endl '\n'
#define mem(arrr, xx) memset(arrr,xx,sizeof arrr)
#define PI acos(-1)
//#define int long long
#define debug(x) cout << (#x) << " = " << x << endl

void Gamal() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
#ifdef Clion
    freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout);
#endif
}

int dx[] = {+0, +0, -1, +1, +1, +1, -1, -1};
int dy[] = {-1, +1, +0, +0, +1, -1, +1, -1};

const int N = 1e6 + 5, M = 1e9 + 7;
int pw[2][N], inv[2][N], pre[2][N], P[2];

int mul(int a, int b) {
    a = (a % M + M) % M;
    b = (b % M + M) % M;
    return 1ll * a * b % M;
}

int add(int a, int b) {
    a = (a % M + M) % M;
    b = (b % M + M) % M;
    return (a + b) % M;
}

int fp(int b, int p) {
    if (!p)return 1;
    int ret = fp(b, p >> 1);
    ret = mul(ret, ret);
    if (p & 1)ret = mul(ret, b);
    return ret;
}

void build() {
    pw[0][0] = pw[1][0] = inv[0][0] = inv[1][0] = pre[0][0] = pre[1][0] = 1;
    int in[2];
    P[0] = 31, P[1] = 37;
    in[0] = fp(P[0], M - 2);
    in[1] = fp(P[1], M - 2);
    for (int i = 1; i < N; ++i) {
        for (int j = 0; j < 2; ++j) {
            pw[j][i] = mul(pw[j][i - 1], P[j]);
            inv[j][i] = mul(inv[j][i - 1], in[j]);
            pre[j][i] = add(pre[j][i - 1], pw[j][i]);
        }
    }
}

struct Hash {
    vector<pii> prefix;

    Hash() {

    }

    Hash(string &s) {
        prefix = vector<pii>(s.size(), {0, 0});
        for (int i = 0; i < s.size(); ++i) {
            prefix[i].fi = mul(s[i] - 'a' + 1, pw[0][i]);
            prefix[i].se = mul(s[i] - 'a' + 1, pw[1][i]);
            if (i) {
                prefix[i].fi = add(prefix[i].fi, prefix[i - 1].fi);
                prefix[i].se = add(prefix[i].se, prefix[i - 1].se);
            }
        }
    }

    pii getRange(int l,int r){
        return {mul(add(prefix[r].fi,-(l ? prefix[l-1].fi:0)),inv[0][l]),
                mul(add(prefix[r].se,-(l ? prefix[l-1].se:0)),inv[1][l])
        };
    }
};


struct SEG{
    pii h={0,0};
    int lz = -1;
    SEG(){

    }
    SEG(pii hh){
        h = hh;
    }
};

struct segTree{
    vector<SEG>seg;
    int sz = 1,n,NO_OP = -1;
    segTree(int nn){
        n = nn;
        while (sz < nn)
            sz *= 2;
        seg.assign(2 * sz,SEG());
    }

    SEG merge(SEG s1,SEG s2){
        SEG ret;
        ret.h.fi = add(s1.h.fi,s2.h.fi);
        ret.h.se = add(s1.h.se,s2.h.se);
        return ret;
    }

    void push(int x,int lx,int rx){
        if(seg[x].lz == NO_OP)return;
        seg[x].h.fi = mul(seg[x].lz, add(pre[0][rx],-(lx ? pre[0][lx-1]:0)));
        seg[x].h.se = mul(seg[x].lz, add(pre[1][rx],-(lx ? pre[1][lx-1]:0)));
        int lf = 2*x+1,rt=2*x+2;
        if(lx != rx){
            seg[lf].lz = seg[x].lz;
            seg[rt].lz = seg[x].lz;
        }
        seg[x].lz = NO_OP;
    }

    void update(int l,int r,int v,int x,int lx,int rx){
        push(x,lx,rx);
        if(l > rx || r < lx)return;
        if(l <= lx && r >= rx){
            seg[x].lz = v;
            push(x,lx,rx);
            return;
        }
        int mid = (lx + rx)/2,lf = 2*x+1,rt=2*x+2;
        update(l,r,v,lf,lx,mid);
        update(l,r,v,rt,mid+1,rx);
        seg[x] = merge(seg[lf],seg[rt]);
    }

    void update(int l,int r,int v){
        update(l,r,v,0,0,n-1);
    }

    SEG query(int l,int r,int x,int lx,int rx){
        push(x,lx,rx);
        if(l <= lx && r >= rx)
            return seg[x];
        if(l > rx || r < lx)
            return SEG();
        int mid = (lx + rx)/2,lf = 2*x+1,rt=2*x+2;
        return merge(query(l,r,lf,lx,mid), query(l,r,rt,mid+1,rx));
    }
    SEG query(int l,int r){
        return query(l,r,0,0,n-1);
    }

};

void solve() {
    int n,q;cin >> n >> q;
    string s;cin >> s;
    vector<string>v(n);
    vector<Hash>h(n);
    for (int i = 0; i < n; ++i) {
        cin >> v[i];
    }
    sort(all(v));
    for (int i = 0; i < n; ++i) h[i] = Hash(v[i]);
    int ptr = -1;
    for (int i = 0; i < n; ++i) {
        if(s > v[i])ptr = i;
        else break;
    }

    segTree st(s.size());
    for (int i = 0; i < s.size(); ++i) {
        st.update(i,i,s[i] - 'a' + 1);
    }
    cout << ptr + 1 << endl;
    while (q--){
        int i;cin >> i;
        char c;cin >> c;
        i--;
        // first i such that s[0,i-1] == v[0,i-1]
        int l = 0,r = n - 1,match = (i ? -1:1);

        if(i){
            int lx = 0,rx = max(ptr,0);
            while (lx <= rx){
                int mid = (lx + rx)/2;
                if(v[mid].size() < i){
                    lx = mid + 1;
                    continue;
                }
                pii a = h[mid].getRange(0,i-1);
                pii b = st.query(0,i-1).h;
                if(a == b){
                    l = mid;
                    match = 1;
                    rx = mid - 1;
                }
                else lx = mid + 1;
            }
            lx = max(ptr,0),rx = n - 1;
            while (lx <= rx){
                int mid = (lx + rx)/2;
                if(v[mid].size() < i){
                    rx = mid - 1;
                    continue;
                }
                pii a = h[mid].getRange(0,i-1);
                pii b = st.query(0,i-1).h;
                if(a == b){
                    match = 1;
                    r = mid;
                    lx = mid + 1;
                }
                else rx = mid - 1;
            }
        }

        if(match != -1){
            ptr = l - 1;
            while (l <= r){
                int mid = (l + r)/2;
                int lx = 1,rx = min(s.size(),v[mid].size()) - i,f = -1;
                while (lx <= rx){
                    int m2 = (lx + rx)/2;
                    pii a = h[mid].getRange(i,i+m2-1);
                    pii b = {mul(pre[0][m2-1], c - 'a' + 1), mul(pre[1][m2-1],c - 'a' + 1)};
                    if(a == b){
                        lx = m2 + 1;
                    }
                    else{
                        f = m2;
                        rx = m2 - 1;
                    }
                }
                if(~f){
                    if(v[mid][i+f-1] > c){
                        r = mid - 1;
                    }
                    else{
                        ptr = mid;
                        l = mid + 1;
                    }
                }
                else{
                    if(v[mid].size() >= s.size()){
                        r = mid - 1;
                    }
                    else{
                        ptr = mid;
                        l = mid + 1;
                    }
                }
            }
        }
        st.update(i,s.size()-1,c-'a'+1);
        cout << ptr + 1 << endl;
    }

}


signed main() {
    Gamal();
    build();
    int t = 1;
//    cin >> t;
    while (t--) {
        solve();
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 16ms
memory: 26976kb

input:

4 3
anatoly
boris
anatooo
anbbbbu
anba
5 o
3 b
7 x

output:

0
0
2
3

result:

ok 4 number(s): "0 0 2 3"

Test #2:

score: 0
Accepted
time: 15ms
memory: 26932kb

input:

5 5
abcde
buz
ababa
build
a
aba
1 b
3 z
2 u
4 z
1 a

output:

3
3
3
4
4
1

result:

ok 6 numbers

Test #3:

score: 0
Accepted
time: 25ms
memory: 27008kb

input:

1 1
abababababababababababab
ababababababababababababab
23 b

output:

0
1

result:

ok 2 number(s): "0 1"

Test #4:

score: 0
Accepted
time: 12ms
memory: 27012kb

input:

4 100
b
dd
ds
ss
sd
1 d
1 s
1 s
1 d
1 s
1 s
1 s
1 s
1 s
1 d
1 s
1 s
1 d
1 d
1 s
1 d
1 d
1 d
1 s
1 d
1 s
1 d
1 s
1 s
1 d
1 d
1 d
1 d
1 s
1 s
1 d
1 s
1 s
1 d
1 d
1 s
1 s
1 s
1 s
1 s
1 s
1 s
1 d
1 d
1 s
1 d
1 s
1 s
1 s
1 s
1 d
1 s
1 s
1 s
1 s
1 s
1 s
1 s
1 d
1 d
1 s
1 d
1 s
1 s
1 d
1 d
1 d
1 d
1 s
1 d
...

output:

0
0
2
2
0
2
2
2
2
2
0
2
2
0
0
2
0
0
0
2
0
2
0
2
2
0
0
0
0
2
2
0
2
2
0
0
2
2
2
2
2
2
2
0
0
2
0
2
2
2
2
0
2
2
2
2
2
2
2
0
0
2
0
2
2
0
0
0
0
2
0
2
2
0
0
2
2
2
0
2
0
0
2
2
2
2
0
0
0
0
2
2
0
2
2
2
2
0
2
2
2

result:

ok 101 numbers

Test #5:

score: 0
Accepted
time: 16ms
memory: 27052kb

input:

10 10
lvv
lvvl
lll
ll
vvll
vl
vllvv
vll
vllvl
llvl
vv
2 l
1 l
3 v
1 v
1 v
3 l
3 l
1 l
2 v
1 v

output:

3
1
1
2
10
10
9
9
1
3
10

result:

ok 11 numbers

Test #6:

score: 0
Accepted
time: 11ms
memory: 26976kb

input:

20 20
ffffqqqfqq
fffqfff
fq
qqfqff
fqfqqqf
fqfqf
fqfffffqfq
fqffffq
qfffqqfq
f
qq
f
fffffqq
q
qqqqffffq
qfqqqfff
ffqff
qqfqfqf
qqfq
qqqqfqqqf
ffqqfffqf
8 f
5 q
8 f
2 q
2 f
3 f
6 f
4 q
2 f
10 f
9 q
10 q
2 q
10 f
5 f
6 f
5 f
7 f
6 f
3 q

output:

3
3
3
3
11
2
2
2
4
2
2
2
2
11
11
11
11
11
11
11
11

result:

ok 21 numbers

Test #7:

score: -100
Wrong Answer
time: 16ms
memory: 26980kb

input:

4 100
enf
gggppp
ppggpg
pggpgp
gppgpg
2 g
2 p
2 p
3 p
1 p
1 g
3 p
1 g
3 p
2 g
3 g
2 p
3 p
3 p
3 p
3 p
2 g
3 g
1 g
2 p
1 g
3 p
1 p
1 p
1 g
2 g
2 g
1 g
1 p
3 g
1 g
3 p
1 g
2 g
1 g
3 g
1 p
3 p
1 p
2 g
2 g
2 g
1 p
3 p
1 p
2 g
2 g
2 p
2 p
2 g
2 p
2 p
2 p
1 g
2 p
1 g
3 p
2 g
3 g
1 g
2 g
1 g
1 p
2 p
1 g
3 ...

output:

0
0
0
0
0
4
0
1
0
1
0
0
1
1
1
1
1
0
0
0
1
0
1
4
4
0
0
0
0
4
3
0
1
0
0
0
0
4
4
4
2
0
0
4
4
4
2
0
0
0
0
0
0
0
0
1
0
1
0
0
0
0
0
4
4
0
1
0
1
0
1
0
0
4
3
4
4
4
4
2
0
0
1
0
0
0
0
1
0
1
0
1
1
0
0
0
1
1
0
1
4

result:

wrong answer 42nd numbers differ - expected: '2', found: '0'