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. linux 学习随笔-系统日常管理常用命令

    1:W 查看系统整体负载,无法查看具体负载,比如内存,磁盘  23:25:20 up 13 min,  2 users,  load average: 0.00, 0.01, 0.01 USER   ...

  2. 使用SignalR实现消息提醒

    Asp.net SignalR是微软为实现实时通信的一个类库.一般情况下,SignalR会使用JavaScript的长轮询(long polling)的方式来实现客户端和服务器通信,随着Html5中W ...

  3. linux下使用tar命令

    解压语法:tar [主选项+辅选项] 文件或者目录 使用该命令时,主选项是必须要有的,它告诉tar要做什么事情,辅选项是辅助使用的,可以选用. 主选项: c 创建新的档案文件.如果用户想备份一个目录或 ...

  4. ios合并静态库

    lipo -create SQY/iOS/iphoneos/libGamePlusAPI.a SQY/iOS/iphonesimulator/libGamePlusAPI.a -output SQY/ ...

  5. Media Queries 详解

    Media Queries直译过来就是“媒体查询”,在我们平时的Web页面中head部分常看到这样的一段代码:  <link href="css/reset.css" rel ...

  6. delphi WebBrowser控件上网页验证码图片识别教程(一)

    步骤一:获取网页中验证码图片的url地址 在delphi中加入一个BitBtn和一个memo以及WebBrowser控件实现网页中验证码图片的url地址的获取 程序如下:procedure TForm ...

  7. 系统集成方案(一).NET集成方案

    NET系统集成有自己独立的登录验证方式.比如,跟报表集成时,不需要再使用报表内置的登录界面,只需要将报表默认的参数用户名fr_username和密码fr_password发送给报表系统,触发一下报表验 ...

  8. css3实现3D立体翻转效果

    1.在IE下无法显示翻转效果,火狐和谷歌可以 /*样式css*/ .nav-menu li { display: inline; } .nav-menu li a { color: #fff; dis ...

  9. JS组件系列——不容错过的两款Bootstrap Icon图标选择组件

    前言:最近好多朋友在群里面聊到bootstrap icon图标的问题,比如最常见的菜单管理,每个菜单肯定需要一个对应的菜单图标,要是有一个可视化的图标选择组件就好了,最好是直接选择图标,就能得到对应的 ...

  10. asp.net MVC 通用登录验证模块

    用法: 还是希望读者把源码看懂,即可运用自如.重点是,为什么有个UserType!!! 登录用户信息: namespace MVCCommonAuth { [Serializable] public ...