1. 程式人生 > >Luogu 4867 Gty的二逼妹子序列

Luogu 4867 Gty的二逼妹子序列

click bool 每一個 add 答案 hid eve 以及 amp

BZOJ3809,是權限題。

我永遠喜歡莫隊。

先莫隊一下移下左右指針,然後用一個數據結構維護一下區間$[a, b]$中的顏色的值,跟著指針移動一起修改修改,每一次$query$的時候就相當於查詢一下$[a, b]$中的和。

其實可以直接對顏色進行分塊,維護一下塊內的值以及每一個位置的答案,每一次修改是$O(1)$的,每一次查詢是$O(\sqrt{n})$的,因為總共要進行$m$次查詢,所以總的時間復雜度是$O((n + m)\sqrt{n})$,這樣寫可以比樹狀數組以及其他的數據結構少一個$log$。

然而這個$log$在你谷上跑的飛快……

最近真是頹了。

Code:

技術分享圖片
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 1e5 + 5;
const int M = 1e6 + 5;

int n, qn, a[N], blo, ans[N];
int cnt[N], bel[N], ln[N], rn[N];

struct Querys {
    int l, r, st, ed, id, ans;
} q[M];

bool cmp(const Querys &x, const Querys &y) { if(bel[x.l] == bel[y.l]) return x.r < y.r; else return x.l < y.l; } inline void read(int &X) { X = 0; char ch = 0; int op = 1; for(; ch > 9 || ch < 0; ch = getchar()) if(ch == -) op = -1; for
(; ch >= 0 && ch <= 9; ch = getchar()) X = (X << 3) + (X << 1) + ch - 48; X *= op; } inline int query(int st, int ed) { int res = 0; if(bel[st] == bel[ed]) { for(int i = st; i <= ed; i++) if(cnt[i]) res++; } else { for(int i = st; i <= rn[bel[st]]; i++) if(cnt[i]) res++; for(int i = ln[bel[ed]]; i <= ed; i++) if(cnt[i]) res++; for(int i = bel[st] + 1; i <= bel[ed] - 1; i++) res += ans[i]; } return res; } inline void add(int x) { ++cnt[a[x]]; if(cnt[a[x]] == 1) ans[bel[a[x]]]++; } inline void del(int x) { --cnt[a[x]]; if(cnt[a[x]] == 0) ans[bel[a[x]]]--; } inline void solve() { sort(q + 1, q + 1 + qn, cmp); for(int l = 1, r = 0, i = 1; i <= qn; i++) { for(; l < q[i].l; del(l++)); for(; l > q[i].l; add(--l)); for(; r < q[i].r; add(++r)); for(; r > q[i].r; del(r--)); q[q[i].id].ans = query(q[i].st, q[i].ed); } } int main() { read(n), read(qn); for(int i = 1; i <= n; i++) read(a[i]); blo = sqrt(n); for(int i = 1; i <= blo; i++) { ln[i] = (i - 1) * blo + 1; rn[i] = i * blo; } if(rn[blo] < n) ++blo, ln[blo] = rn[blo - 1] + 1, rn[blo] = n; for(int i = 1; i <= blo; i++) { for(int j = ln[i]; j <= rn[i]; j++) bel[j] = i; } for(int i = 1; i <= qn; i++) { read(q[i].l), read(q[i].r), read(q[i].st), read(q[i].ed); q[i].id = i; } solve(); for(int i = 1; i <= qn; i++) printf("%d\n", q[i].ans); return 0; }
View Code

Luogu 4867 Gty的二逼妹子序列