BZOJ 3236: [Ahoi2013]作业
3236: [Ahoi2013]作业
Time Limit: 100 Sec Memory Limit: 512 MB
Submit: 1393 Solved: 562
[Submit][Status][Discuss]
Description
.jpg)
Input

Output

Sample Input
1 2 2
1 2 1 3
1 2 1 1
1 3 1 3
2 3 2 3
Sample Output
1 1
3 2
2 1
HINT
N=100000,M=1000000
Source
莫队算法 + 树状数组统计答案
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; /* SCANNER */ #define siz 10000000 inline char get_a(void) {
static char buf[siz], *bit = buf; if (bit == buf + siz)
fread(bit = buf, , siz, stdin); return *bit++;
} inline int get_i(void) {
register int ret = ;
register int neg = false;
register int bit = get_a(); for (; bit < ''; bit = get_a())
if (bit == '-')neg ^= true; for (; bit >= ''; bit = get_a())
ret = ret * + bit - ''; return neg ? -ret : ret;
} #define maxn 400005
#define maxm 1000005 int s;
int tot;
int n, m;
int num[maxn];
int cnt[maxn];
int tmp[maxn];
int ans1[maxm];
int ans2[maxm];
int tree1[maxn];
int tree2[maxn]; struct query {
int l, r, a, b, id;
}qry[maxm]; inline int cmp(const void *a, const void *b) {
query *A = (query *)a;
query *B = (query *)b;
if (A->l / s != B->l / s)
return A->l - B->l;
else
return A->r - B->r;
} inline void add(int *t, int p, int k) {
for (; p <= tot; p += p&-p)
t[p] += k;
} inline int ask(int *t, int p) {
int ret = ;
for (; p; p -= p&-p)
ret += t[p];
return ret;
} inline void remove(int t) {
add(tree1, t, -);
if (--cnt[t] == )
add(tree2, t, -);
} inline void insert(int t) {
add(tree1, t, );
if (++cnt[t] == )
add(tree2, t, );
} signed main(void) {
n = get_i();
m = get_i();
s = sqrt(n); for (int i = ; i <= n; ++i)
num[i] = get_i(), tmp[++tot] = num[i]; for (int i = ; i <= m; ++i) {
qry[i].id = i;
qry[i].l = get_i();
qry[i].r = get_i();
qry[i].a = get_i();
qry[i].b = get_i();
} for (int i = ; i <= m; ++i)
tmp[++tot] = qry[i].a,
tmp[++tot] = qry[i].b; sort(tmp + , tmp + + tot); tot = unique(tmp + , tmp + + tot) - tmp; for (int i = ; i <= n; ++i)
num[i] = lower_bound(tmp + , tmp + tot, num[i]) - tmp; for (int i = ; i <= m; ++i) {
qry[i].a = lower_bound(tmp + , tmp + tot, qry[i].a) - tmp;
qry[i].b = lower_bound(tmp + , tmp + tot, qry[i].b) - tmp;
} /*
for (int i = 1; i <= n; ++i)
printf("%d ", num[i]); puts(""); for (int i = 1; i <= m; ++i)
printf("%d %d\n", qry[i].a, qry[i].b);
*/ qsort(qry + , m, sizeof(query), cmp); int l = , r = ; for (int i = ; i <= m; ++i) {
while (l < qry[i].l)remove(num[l++]);
while (l > qry[i].l)insert(num[--l]);
while (r < qry[i].r)insert(num[++r]);
while (r > qry[i].r)remove(num[r--]);
ans1[qry[i].id] = ask(tree1, qry[i].b) - ask(tree1, qry[i].a - );
ans2[qry[i].id] = ask(tree2, qry[i].b) - ask(tree2, qry[i].a - );
} for (int i = ; i <= m; ++i)
printf("%d %d\n", ans1[i], ans2[i]); //system("pause");
}
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; /* SCANNER */ #define siz 50000000 inline int get_c(void)
{
static char buf[siz];
static char *head = buf;
static char *tail = buf + siz; if (head == tail)
fread(head = buf, , siz, stdin); return *head++;
} #define getc get_c
// #define getc getchar inline int get_i(void)
{
register int ret = ;
register int neg = false;
register int bit = getc(); for (; bit < ''; bit = getc())
if (bit == '-')neg ^= true; for (; bit >= ''; bit = getc())
ret = ret * + bit - ''; return neg ? -ret : ret;
} /* PROBLEM */ #define maxn 100005
#define maxm 1000005 int n, m, s;
int num[maxn];
int cnt[maxm * ];
int tmp[maxm * ];
int *tot = tmp + ;
int tree1[maxm * ];
int tree2[maxm * ]; /* QRY */ struct query
{
int l, r;
int a, b;
int ans1;
int ans2;
}qry[maxm], *ord[maxm]; inline bool cmp(query *a, query *b)
{
if (a->l / s != b->l / s)
return a->l < b->l;
else
return a->r < b->r;
} /* BIT */ inline void add(int *t, int p, int k)
{
int len = tot - tmp;
for (; p <= len; p += p&-p)
t[p] += k;
} inline int ask(int *t, int p)
{
int ret = ;
for (; p; p -= p&-p)
ret += t[p];
return ret;
} /* MOQ */ inline void insert(int t)
{
add(tree1, t, +);
if (++cnt[t] == )
add(tree2, t, +);
} inline void remove(int t)
{
add(tree1, t, -);
if (--cnt[t] == )
add(tree2, t, -);
} /* MAIN */ signed main(void)
{
n = get_i();
m = get_i();
s = sqrt(n); for (int i = ; i <= n; ++i)
*tot++ = num[i] = get_i(); for (int i = ; i <= m; ++i)
{
ord[i] = qry + i;
qry[i].l = get_i();
qry[i].r = get_i();
*tot++ = qry[i].a = get_i();
*tot++ = qry[i].b = get_i();
} sort(tmp + , tot); tot = unique(tmp + , tot); for (int i = ; i <= n; ++i)
num[i] = lower_bound(tmp + , tot, num[i]) - tmp; for (int i = ; i <= m; ++i)
{
qry[i].a = lower_bound(tmp + , tot, qry[i].a) - tmp;
qry[i].b = lower_bound(tmp + , tot, qry[i].b) - tmp;
} sort(ord + , ord + + m, cmp); int lt = , rt = ; // left & right for (int i = ; i <= m; ++i)
{
query *q = ord[i];
while (lt < q->l)remove(num[lt++]);
while (lt > q->l)insert(num[--lt]);
while (rt < q->r)insert(num[++rt]);
while (rt > q->r)remove(num[rt--]);
q->ans1 = ask(tree1, q->b) - ask(tree1, q->a - );
q->ans2 = ask(tree2, q->b) - ask(tree2, q->a - );
} for (int i = ; i <= m; ++i)
printf("%d %d\n", qry[i].ans1, qry[i].ans2); //system("pause");
}
@Author: YouSiki
BZOJ 3236: [Ahoi2013]作业的更多相关文章
- Bzoj 3236: [Ahoi2013]作业 莫队,分块
3236: [Ahoi2013]作业 Time Limit: 100 Sec Memory Limit: 512 MBSubmit: 1113 Solved: 428[Submit][Status ...
- BZOJ 3236: [Ahoi2013]作业( 莫队 + BIT )
莫队..用两个树状数组计算.时间复杂度应该是O(N1.5logN). 估计我是写残了...跑得很慢... ----------------------------------------------- ...
- bzoj 3236: [Ahoi2013]作业(缺线段树)
3236: [Ahoi2013]作业 Time Limit: 100 Sec Memory Limit: 512 MBSubmit: 1744 Solved: 702[Submit][Status ...
- [BZOJ 3236] [Ahoi2013] 作业 && [BZOJ 3809] 【莫队(+分块)】
题目链接: BZOJ - 3236 BZOJ - 3809 算法一:莫队 首先,单纯的莫队算法是很好想的,就是用普通的第一关键字为 l 所在块,第二关键字为 r 的莫队. 这样每次端点移动添加或删 ...
- BZOJ 3236: [Ahoi2013]作业(莫队+树状数组)
传送门 解题思路 莫队+树状数组.把求\([a,b]\)搞成前缀和形式,剩下的比较裸吧,用\(cnt\)记一下数字出现次数.时间复杂度\(O(msqrt(n)log(n)\),莫名其妙过了. 代码 # ...
- 树套树专题——bzoj 3110: [Zjoi2013] K大数查询 & 3236 [Ahoi2013] 作业 题解
[原题1] 3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 978 Solved: 476 Descri ...
- BZOJ 3809: Gty的二逼妹子序列 & 3236: [Ahoi2013]作业 [莫队]
题意: 询问区间权值在$[a,b]$范围内种类数和个数 莫队 权值分块维护种类数和个数$O(1)-O(\sqrt{N})$ #include <iostream> #include < ...
- BZOJ 3236 AHOI 2013 作业 莫队+树状数组
BZOJ 3236 AHOI 2013 作业 内存限制:512 MiB 时间限制:10000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目大意: 此时己是凌晨两点,刚刚做了Co ...
- 【BZOJ3809/3236】Gty的二逼妹子序列 [Ahoi2013]作业 莫队算法+分块
[BZOJ3809]Gty的二逼妹子序列 Description Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题. 对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b ...
随机推荐
- 在Mac电脑上为iPhone或iPad录屏的方法
在以前的Mac和iOS版本下,录制iPhone或者iPad屏幕操作是一件稍微复杂的事情.但是随着Yosemite的出现,在Mac电脑上为iPhone或iPad录屏的方法就变得简单了.下面就介绍一下具体 ...
- SQL Server自动化运维系列——监控磁盘剩余空间及SQL Server错误日志(Power Shell)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在所有的自检流程中最基础的一个就是磁盘剩余空间检测. ...
- eclipse svn分支与合并操作
以前做项目的时候没有用过svn的分支合并操作,今天用到了,刚开始还真不会啊.最后查了下就是这么的方便.专门记录下来. 原文来自:http://blog.csdn.net/lisq037/article ...
- 4412开发板搭建Uboot、Kernel和Android4.0的编译环境方法
本文转自迅为4412开发板实战教程书籍:http://www.topeetboard.com 迅为是基于Ubuntu12.04.2平台做开发,所有的配置和编译脚本也是基于此平台,没有在其它平台上测试过 ...
- ios合并静态库
lipo -create SQY/iOS/iphoneos/libGamePlusAPI.a SQY/iOS/iphonesimulator/libGamePlusAPI.a -output SQY/ ...
- linux上安装subversion
1.安装svn服务器端 yum install subversion 从镜像下载安装svn服务器端 中间会提示是否ok,输入y,确认 安装成功提示:.....complete! 依次执行 ...
- hammer.js的六大事件
1.Pan事件:在指定的dom区域内,一个手指放下并移动事件,即触屏中的拖动事件.这个事件在触屏开发中比较常用: Panstart 拖动开始 Panmove 拖动过程 Panend 拖动结束 Panc ...
- frakti && RunPodSandbox 源码分析
listen = flag.String("listen", "/var/run/frakti.sock", "...") hyperEnd ...
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose) [莫队算法]【学习笔记】
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 7687 Solved: 3516[Subm ...
- 第二章 spring
一.Bean作用域 spring容器创建的时候,会将所有配置的bean对象创建出来,默认bean都是单例的.代码通过getBean()方法从容器获取指定的bean实例,容器首先会调用Bean类的无参构 ...