1. 程式人生 > >Luogu4424 HNOI/AHOI2018 尋寶遊戲 神仙題

Luogu4424 HNOI/AHOI2018 尋寶遊戲 神仙題

show read clas emc == www. b- 進制 [1]

傳送門


好神仙的題目啊……

二進制下,\(\land 1\)\(\lor 0\)實際上是沒有意義的,而\(\land 0\)強制這一位變為\(0\)\(\lor 1\)強制這一位變為\(1\)

那麽如果某一位的答案要為\(0\),也就意味著:要麽同時不存在\(\land 0\)\(\lor 1\),要麽最後一個\(\land 0\)後面不能有\(\lor 1\)。答案為\(1\)同理。

那麽對於每一位,將所有\(a_i\)在這一位上的值從右往左看作一個二進制數\(x\),將操作序列\(\land\)對應為\(1\)\(\lor\)對應為\(0\),從右往左看作一個二進制數\(op\),那麽如果答案的這一位為\(0\)

,必須滿足\(op \geq x\)。反之則要滿足\(op < x\)

那麽最後的答案就會表現為\(a \leq op < b\)的形式,答案為\(b-a\)

那麽將所有\(x\)排好序,每一次掃一遍找到\(a\)\(b\)就可以了。註意可能出現\(a>b\)的情況。

#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;

inline int read(){
    int a = 0;
    char c = getchar();
    bool f = 0;
    while(!isdigit(c)){
        if(c == ‘-‘)
            f = 1;
        c = getchar();
    }
    while(isdigit(c)){
        a = (a << 3) + (a << 1) + (c ^ ‘0‘);
        c = getchar();
    }
    return f ? -a : a;
}

const int MOD = 1e9 + 7;
int val[5010] , ind[5010] , tmp[5010];
int N , M , Q , cnt[2];
char s[5010];

int main(){
    #ifndef ONLINE_JUDGE
    //freopen("in" , "r" , stdin);
    //freopen("out" , "w" , stdout);
    #endif
    N = read();
    M = read();
    Q = read();
    for(int i = 1 ; i <= M ; ++i)
        ind[i] = i;
    int times = 1;
    for(int i = 1 ; i <= N ; ++i){
        scanf("%s" , s + 1);
        cnt[0] = cnt[1] = 0;
        for(int j = 1 ; j <= M ; ++j)
            if(s[j] == ‘0‘)
                ++cnt[1];
            else
                val[j] = (val[j] + times) % MOD;
        for(int j = 1 ; j <= M ; ++j)
            tmp[++cnt[s[ind[j]] - ‘0‘]] = ind[j];
        memcpy(ind , tmp , sizeof(int) * (M + 1));
        times = (times << 1) % MOD;
    }
    for(int i = 1 ; i <= Q ; ++i){
        scanf("%s" , s + 1);
        int L = 0 , R = times , indl = 0 , indr = M + 1;
        for(int j = M ; j ; --j)
            if(s[ind[j]] == ‘0‘){
                indl = j;
                L = val[ind[j]];
                break;
            }
        for(int j = 1 ; j <= M ; ++j)
            if(s[ind[j]] == ‘1‘){
                indr = j;
                R = val[ind[j]];
                break;
            }
        if(indr < indl)
            cout << 0 << ‘\n‘;
        else
            cout << (R - L + MOD) % MOD << ‘\n‘;
    }
    return 0;
}

?

Luogu4424 HNOI/AHOI2018 尋寶遊戲 神仙題