BZOJ 3236: [Ahoi2013]作业( 莫队 + BIT )
2015-09-03 14:32
567 查看
![](http://images2015.cnblogs.com/blog/723896/201509/723896-20150903142907028-513731261.png)
莫队..用两个树状数组计算.时间复杂度应该是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 MBSubmit: 899 Solved: 345
[Submit][Status][Discuss]
Description
![](http://www.lydsy.com/JudgeOnline/upload/201306/1(2).jpg)
Input
![](http://www.lydsy.com/JudgeOnline/upload/201306/2.jpg)
Output
![](http://www.lydsy.com/JudgeOnline/upload/201306/3.jpg)
Sample Input
3 41 2 2
1 2 1 3
1 2 1 1
1 3 1 3
2 3 2 3
Sample Output
2 21 1
3 2
2 1
HINT
N=100000,M=1000000Source
By wangyisong1996加强数据相关文章推荐
- HDU 2544 最短路(spfa)
- JAVA基础学习(三)---程序结构与控制、函数与数组入门
- 使用xcode创建开发证书和打包证书
- redis事务及锁应用
- hadoop单机安装与分布式安装
- 【9-2】mysql数据库学习01
- 在Centos中安装并配置phpMyAdmin
- Activity传递数据(四)获得返回数据
- 1080. Graduate Admission (30)
- 在Ubuntu下修改sublime默认模板代码
- 关于线程锁的学习
- HDU 5381 The sum of gcd 询问区间内所有子区间的GCD和 [暴力法]
- 心路历程(一)-自学java两个月心得
- 二叉树操作Java
- MVC常用
- Drupal安装百度编辑器Ueditor for wysiwyg
- 快速选择算法
- iOS软件开发之在UIScrollView上添加手势不能触发解决办法
- Java拾遗------IO流
- DX控件循环找控件