您的位置:首页 > 其它

BZOJ 3236: [Ahoi2013]作业( 莫队 + BIT )

2015-09-03 14:32 567 查看


莫队..用两个树状数组计算.时间复杂度应该是O(N1.5logN). 估计我是写残了...跑得很慢...

-------------------------------------------------------------------------

#include<bits/stdc++.h> using namespace std; #define lowbit(x) ((x) & -(x)) const int maxn = 100009;const int maxm = 1000009; int N, M, block[maxn], seq[maxn], ans[maxm][2], L, R; inline int read() { int ans = 0; char c = getchar(); for(; !isdigit(c); c = getchar()); for(; isdigit(c); c = getchar()) ans = ans * 10 + c - '0'; return ans;} int buf[12];inline void write(int x) { if(!x) { putchar('0'); return; } int n = 0; for(; x; x /= 10) buf[n++] = x % 10; while(n--) putchar(buf
+ '0');} struct BIT { int b[maxn]; BIT() { memset(b, 0, sizeof b); } inline void update(int x, int v) { for(; x <= N; x += lowbit(x)) b[x] += v; } inline int sum(int x) { int ret = 0; for(; x; x -= lowbit(x)) ret += b[x]; return ret; } inline int query(int l, int r) { return sum(r) - sum(l - 1); }} cnt, exist; struct Q { int l, r, a, b, p; inline void Read(int t) { l = read() - 1; r = read() - 1; a = read(); b = read(); p = t; } bool operator < (const Q &o) const { return block[l] < block[o.l] || (block[l] == block[o.l] && r < o.r); }} A[maxm]; void init() { N = read(); M = read(); for(int i = 0; i < N; i++) seq[i] = read(); int blocks = (int) sqrt(N); for(int i = 0; i < N; i++) block[i] = i / blocks; for(int i = 0; i < M; i++) A[i].Read(i);} void work(int x) { Q* c = A + x; for(; L < c->l; L++) { cnt.update(seq[L], -1); if(!cnt.query(seq[L], seq[L])) exist.update(seq[L], -1); } while(L > c->l) { L--; if(!cnt.query(seq[L], seq[L])) exist.update(seq[L], 1); cnt.update(seq[L], 1); } for(; R > c->r; R--) { cnt.update(seq[R], -1); if(!cnt.query(seq[R], seq[R])) exist.update(seq[R], -1); } while(R < c->r) { R++; if(!cnt.query(seq[R], seq[R])) exist.update(seq[R], 1); cnt.update(seq[R], 1); } ans[c->p][0] = cnt.query(c->a, c->b); ans[c->p][1] = exist.query(c->a, c->b);} int main() { init(); sort(A, A + M); cnt.update(seq[L = R = 0], 1); exist.update(seq[0], 1); for(int i = 0; i < M; i++) work(i); for(int i = 0; i < M; i++) { write(ans[i][0]); putchar(' '); write(ans[i][1]); putchar('\n'); } return 0;}-------------------------------------------------------------------------

3236: [Ahoi2013]作业

Time Limit: 100 Sec Memory Limit: 512 MB
Submit: 899 Solved: 345
[Submit][Status][Discuss]

Description



Input



Output



Sample Input

3 4
1 2 2
1 2 1 3
1 2 1 1
1 3 1 3
2 3 2 3

Sample Output

2 2
1 1
3 2
2 1

HINT

N=100000,M=1000000

Source

By wangyisong1996加强数据
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: