Submission #1329021

#TimeUsernameProblemLanguageResultExecution timeMemory
1329021nathjessMađioničar (COI22_madionicar)C++20
25 / 100
273 ms4468 KiB
# include <bits/stdc++.h>
# define int long long
# define vi vector<int>
# define pb push_back
# define pii pair<int, int>
# define fi first
# define se second

using namespace std;

int n, pref[100005], suff[100005], pow_key[100005];
vi odd, even, v;
const int MOD=1e9+7;

bool ask(int l, int r) {
    cout << "? " << l << " " << r << endl;
    int ret; cin >> ret;
    return ret;
}

char sm(char a) {return a;}

char ex(char a) {
    if(a=='a') return 'b';
    return 'a';
}

void hassh() {
    pow_key[0]=1;
    for(int i=1; i<=n; i++) {
        pref[i]=pref[i-1]*3+(v[i-1]-'a'+1);
        pref[i]%=MOD;
        pow_key[i]=pow_key[i-1]*3;
        pow_key[i]%=MOD;
    }
    for(int i=n; i>=1; i--) {
        suff[i]=suff[i+1]*3+(v[i-1]-'a'+1);
        suff[i]%=MOD;
    }
}

int getpref(int l, int r) {
    int dif=r-l+1;
    return ((((pref[r]-pref[l-1]*pow_key[dif])%MOD)+MOD)%MOD);
}

int getsuf(int l, int r) {
    int dif=r-l+1;
    return ((((suff[l]-suff[r+1]*pow_key[dif])%MOD)+MOD)%MOD);
}

void solve () {
    cin >> n;
    for(int i=1; i<=n; i++) {
        if(i%2==1) odd.pb(i);
        else even.pb(i);
    }
    v.pb('a');
    for(int i=2; i<=n; i++) {
        if(ask(i-1, i)) {
            v.pb(sm(v.back()));
        } else {
            v.pb(ex(v.back()));
        }
    }
    hassh();
    int l=0, r=odd.size()-1, ret=0;
    while(l<=r) {
        int mid=(l+r)/2, sz=odd[mid], ok=0;
        for(int i=1; i<=(n-sz+1); i++) {
            int dep=i+(sz-1)/2 - 1;
            int blk=i+sz-1 - (sz-1)/2 + 1;
            if(getpref(i, dep)==getsuf(blk, i+sz-1)) {
                ok=1;
                break;
            }
        }
        if(ok) l=mid+1, ret=mid;
        else r=mid-1;
    }
    int ans=odd[ret];
    l=0, r=even.size()-1, ret=-1;
    while(l<=r) {
        int mid=(l+r)/2, sz=even[mid], ok=0;
        for(int i=1; i<=(n-sz+1); i++) {
            int dep=i+sz/2 - 1;
            int blk=i+sz-1 - sz/2 + 1;
            if(getpref(i, dep)==getsuf(blk, i+sz-1)) {
                ok=1;
                break;
            }
        }
        if(ok) l=mid+1, ret=mid;
        else r=mid-1;
    }
    if(ret!=-1) ans=max(ans, even[ret]);
    cout << "! " << ans << endl;
}
 
signed main() {
   solve();
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...