3236: [Ahoi2013]作业

Time Limit: 100 Sec  Memory Limit: 512 MB
Submit: 1393  Solved: 562
[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

[Submit][Status][Discuss]

莫队算法 + 树状数组统计答案

 #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]作业的更多相关文章

  1. Bzoj 3236: [Ahoi2013]作业 莫队,分块

    3236: [Ahoi2013]作业 Time Limit: 100 Sec  Memory Limit: 512 MBSubmit: 1113  Solved: 428[Submit][Status ...

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

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

  3. bzoj 3236: [Ahoi2013]作业(缺线段树)

    3236: [Ahoi2013]作业 Time Limit: 100 Sec  Memory Limit: 512 MBSubmit: 1744  Solved: 702[Submit][Status ...

  4. [BZOJ 3236] [Ahoi2013] 作业 && [BZOJ 3809] 【莫队(+分块)】

    题目链接: BZOJ - 3236   BZOJ - 3809 算法一:莫队 首先,单纯的莫队算法是很好想的,就是用普通的第一关键字为 l 所在块,第二关键字为 r 的莫队. 这样每次端点移动添加或删 ...

  5. BZOJ 3236: [Ahoi2013]作业(莫队+树状数组)

    传送门 解题思路 莫队+树状数组.把求\([a,b]\)搞成前缀和形式,剩下的比较裸吧,用\(cnt\)记一下数字出现次数.时间复杂度\(O(msqrt(n)log(n)\),莫名其妙过了. 代码 # ...

  6. 树套树专题——bzoj 3110: [Zjoi2013] K大数查询 &amp; 3236 [Ahoi2013] 作业 题解

    [原题1] 3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 978  Solved: 476 Descri ...

  7. BZOJ 3809: Gty的二逼妹子序列 & 3236: [Ahoi2013]作业 [莫队]

    题意: 询问区间权值在$[a,b]$范围内种类数和个数 莫队 权值分块维护种类数和个数$O(1)-O(\sqrt{N})$ #include <iostream> #include < ...

  8. BZOJ 3236 AHOI 2013 作业 莫队+树状数组

    BZOJ 3236 AHOI 2013 作业 内存限制:512 MiB 时间限制:10000 ms 标准输入输出     题目类型:传统 评测方式:文本比较 题目大意: 此时己是凌晨两点,刚刚做了Co ...

  9. 【BZOJ3809/3236】Gty的二逼妹子序列 [Ahoi2013]作业 莫队算法+分块

    [BZOJ3809]Gty的二逼妹子序列 Description Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题. 对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b ...

随机推荐

  1. log4j配置

    log4j.rootCategory=DEBUG , R, D,stdout # Console log4j.appender.stdout=org.apache.log4j.ConsoleAppen ...

  2. Android 四大组件之再论service

    service常见的有2种方式,本地service以及remote service. 这2种的生命周期,同activity的通信方式等,都不相同. 关于这2种service如何使用,这里不做介绍,只是 ...

  3. 使用eclipse开发Morphline的Java代码段

    背景:morphline是一个轻量级的etl工具.除了提供标准化的方法之外,还可以定制化的开发java片段.定制化的java片段会在加载时被作为一个独立的类编译,对源数据作处理. morphline关 ...

  4. 使用Sqoop从MySQL导入数据到Hive和HBase 及近期感悟

    使用Sqoop从MySQL导入数据到Hive和HBase 及近期感悟 Sqoop 大数据 Hive HBase ETL 使用Sqoop从MySQL导入数据到Hive和HBase 及近期感悟 基础环境 ...

  5. 穿越之旅之--android中如何执行java命令

    android的程序基于java开发,当我们接上调试器,执行adb shell,就可以执行linux命令,但是却并不能执行java命令. 那么在android的shell中是否就不能执行java程序了 ...

  6. WPF 自定义CheckBox

    WPF中原始的CheckBox样式很简单,有时候不适用于WPF那种炫酷的界面. 本章节讲述如何设计一个匹配业务需要.好看的CheckBox(继上篇<WPF-自定义ListBox>中的Che ...

  7. kafka集群安装

    主要需要设置的是conf文件夹中的server.properties文件, broker.id,不同的机器节点,使用不同的id号,不能重复. num.network.threads=8 num.par ...

  8. java报表工具FineReport常用函数的用法总结(文本和日期函数)

    文本函数 CHAR CHAR(number):根据指定数字返回对应的字符.CHAR函数可将计算机其他类型的数字代码转换为字符. Number:用于指定字符的数字,介于1Number:用于指定字符的数字 ...

  9. django url路径与模板中样式相对路径的问题

    static目录下有css和js及image等文件夹,里面放置网站的一些静态文件,static位于网站根目录下,django中配置静态文件这个就细说,网上都有,昨天在添加新内容时发现一个问题,我的ur ...

  10. 利用firebug调试功能辅助了解闭包和this

    算一算,有段时间没写博客. 上午的时候翻看以前收藏的一个系列博文<深入理解javascript原型和闭包>, 讲闭包那节:http://www.cnblogs.com/wangfupeng ...