【題解】tty's sequence
阿新 • • 發佈:2021-10-07
前言
祝願豬豬早日康復。
昨天在 \(202\) 看 QYB 和 LSC 搞黃(
所以沒時間洗衣服了,洗澡的時候都是開水。
所以定了 \(12:00,12:01,12:02\) 三個鬧鐘想起來洗衣服,然後一覺睡到 \(6:20\),室友人不在,鬧鐘響了(
當時覺得很奇怪為什麼鬧鐘沒響,但是太困了就繼續睡了。
結果一起來看手機顯示 \(8:49\)!
馬上跳起來把眼鏡摘瞭然後叫上 DYY 一起跑。
到機房已經沒了半小時了。
可以感覺到已經炸了。
\(res:135pts\)
\(\text{Description}\)
給定一個長度為 \(n\) 的數列以及 \(k\),請求出兩個長度 \(\ge k\)
- 對於 \(30\%\) 的資料,\(n,k\le100\)。
- 對於另外 \(30\%\) 的資料,\(k\le10\)。
- 對於 \(100\%\) 的資料,\(1\le k\le n\le1000000\),數列中的每個數在 \([0,2^{31}-1]\) 範圍內。
\(\text{Solution}\)
我們考慮每一位:
原數 | 0 | 0 | 1 | 1 |
---|---|---|---|---|
新數 | 0 | 1 | 0 | 1 |
\(\rm or\) 值 | 0 | 1 | 1 | 1 |
\(\rm and\) 值 | 0 | 0 | 0 | 1 |
\(\rm or\) 後不可能變小,\(\rm and\) 後不可能變大。
所以 \(\rm or\) 最大就是所有數 \(\rm or\) 起來,\(\rm and\) 最大就是 \(\max\{\) 所有長度為 \(k\) 的子串的 $ \rm and$ 值 \(\}\)
結果看到這個長度為 \(k\) 的子串沒想到線段樹(
時間複雜度 \(\mathcal{O}((n-k)\log k)\)。
\(\text{Code}\)
#include <iostream> #include <cstdio> using namespace std; const int MAXN = 1e6 + 5; int a[MAXN]; #define lson pos << 1 #define rson pos << 1 | 1 struct tree { int l, r, val; }t[MAXN << 2]; void pushup(int pos) { t[pos].val = t[lson].val & t[rson].val; } void build(int pos, int l, int r) { t[pos].l = l, t[pos].r = r; if (l == r) { t[pos].val = a[l]; return; } int mid = (l + r) >> 1; build(lson, l, mid); build(rson, mid + 1, r); pushup(pos); } int query(int pos, int L, int R) { int l = t[pos].l, r = t[pos].r; if (L <= l && r <= R) { return t[pos].val; } int mid = (l + r) >> 1, res = 0x7fffffff; if (L <= mid) { res &= query(lson, L, R); } if (R > mid) { res &= query(rson, L, R); } return res; } int main() { int n, k, ans1 = 0, ans2 = 0; scanf("%d%d", &n, &k); for (int i = 1; i <= n; i++) { scanf("%d", a + i); ans1 |= a[i]; } printf("%d ", ans1); build(1, 1, n); for (int i = 1; i <= n - k + 1; i++) { ans2 = max(ans2, query(1, i, i + k - 1)); } printf("%d\n", ans2); return 0; }