CF 655E E. Beautiful Subarrays (ED_12_E)

題意

給你一個(gè)大小為n(1 <= n <= 10 ^ 6)的 int 數(shù)組,找出連續(xù)子串的個(gè)數(shù),滿足連續(xù)子串的亦或值至少為k(1 <= k <= 10 ^ 9)

思路

字典樹

代碼

#define rep(i, n) for (int i = 0; i < (n); i++)
#define FOR(i, n, m) for (int i = (n); i <= (m); i++)
#define FORD(i, n, m) for (int i = (n); i >= (m); i--)

const int N = 30e6 + 5, L = 30;

int n, m, e, d;
int ch[N][2];
int wv[N];

void init() {
    e = 1, wv[0] = 0;
    ch[0][0] = ch[0][1] = -1;
}

void add(int x) {
    int p = 0, id;
    wv[p]++;
    //sc(x);
    FORD (i, L - 1, 0) {
        id = (x >> i) & 1;
        //sc3(p, id, ch[p][id]);
        if (ch[p][id] == -1) {
            ch[e][0] = ch[e][1] = -1;
            wv[e] = 0;
            ch[p][id] = e++;
        }
        p = ch[p][id], wv[p]++;
        //sc3(p, wv[p], e);
    }
}

int cal() {
    int ans = 0, p = 0, id, x;
    FORD (i, L - 1, 0) {
        id = (m >> i) & 1, x =  (d >> i) & 1 ^ 1;
        if (id) {                   // for bit = 1
            if (ch[p][x] == -1) return ans;
            p = ch[p][x];
        } else {                    // for bit = 0
            if (ch[p][x] != -1) ans += wv[ch[p][x]];
            if (ch[p][x ^ 1] != -1) p = ch[p][x ^ 1];
            else return ans;
        }
    }
    return ans + wv[p];
}

int main() {
    int x;
    LL ans;
    while (~scanf("%d %d", &n, &m)) {
        init();
        ans = 0, d = 0;
        rep (i, n) {
            scanf("%d", &x);
            add(d);
            d ^= x;
            ans += cal();
        }
        cout << ans << '\n';
    }
    return 0;
}

再來個(gè)指針版本

#define rep(i, n) for (int i = 0; i < (n); i++)
#define FOR(i, n, m) for (int i = (n); i <= (m); i++)
#define FORD(i, n, m) for (int i = (n); i >= (m); i--)

const int N = 30e6 + 5, L = 30;

struct Node {
    Node *ch[2];
    int val;

    Node() {
        ch[0] = ch[1] = NULL;
        val = 0;
    }

} *root;

int n, m, e, d;

void init() {
    root = new Node();
}

void add(int x) {
    int id;
    Node *p = root;
    p->val ++;
    FORD (i, L - 1, 0) {
        id = (x >> i) & 1;
        if (p->ch[id] == NULL) {
            Node *tmp = new Node();
            p->ch[id] = tmp;
        }
        p = p->ch[id], p->val ++;
    }
}

int cal() {
    int ans = 0, id, x;
    Node *p = root;
    FORD (i, L - 1, 0) {
        id = (m >> i) & 1, x =  (d >> i) & 1 ^ 1;
        if (id) {                   // for bit = 1
            if (p->ch[x] == NULL) return ans;
            p = p->ch[x];
        } else {                    // for bit = 0
            if (p->ch[x] != NULL) ans += p->ch[x]->val;
            if (p->ch[x ^ 1] != NULL) p = p->ch[x ^ 1];
            else return ans;
        }
    }
    return ans + p->val;
}

int main() {
    int x;
    LL ans;
    while (~scanf("%d %d", &n, &m)) {
        init();
        ans = 0, d = 0;
        rep (i, n) {
            scanf("%d", &x);
            add(d);
            d ^= x;
            ans += cal();
        }
        printf("%I64d\n", ans);
    }
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗(yàn)。 張土汪:刷leetcod...
    土汪閱讀 12,921評(píng)論 0 33
  • 指針是C語言中廣泛使用的一種數(shù)據(jù)類型。 運(yùn)用指針編程是C語言最主要的風(fēng)格之一。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu); ...
    朱森閱讀 3,614評(píng)論 3 44
  • 一、基本數(shù)據(jù)類型 注釋 單行注釋:// 區(qū)域注釋:/* */ 文檔注釋:/** */ 數(shù)值 對(duì)于byte類型而言...
    龍貓小爺閱讀 4,452評(píng)論 0 16
  • 【程序1】 題目:古典問題:有一對(duì)兔子,從出生后第3個(gè)月起每個(gè)月都生一對(duì)兔子,小兔子長到第三個(gè)月后每個(gè)月又生一對(duì)兔...
    葉總韓閱讀 5,226評(píng)論 0 41
  • 練習(xí)了幾張水彩卡片的上色,找到了一點(diǎn)感覺。 關(guān)于疊色,濕畫、干畫,調(diào)色,有了大概的認(rèn)識(shí)。以后慢慢寫出來。 看圖: ...
    綰念閱讀 594評(píng)論 0 3

友情鏈接更多精彩內(nèi)容