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 ...
随机推荐
- iOS之UIApplication详解
UIApplication对象特点: 特点1: UIApplication对象是应用程序的象征,一个UIApplication对象就代表一个应用程序,而且是单例的.(用来封装整个应用程序的一个对象, ...
- MongoDB学习笔记~环境搭建
回到目录 Redis学习笔记已经告一段落,Redis仓储也已经实现了,对于key/value结构的redis我更愿意使用它来实现数据集的缓存机制,而对于结构灵活,查询效率高的时候使用redis就有点不 ...
- 分布式搜索引擎Elasticsearch的简单使用
官方网址:https://www.elastic.co/products/elasticsearch/ 一.特性 1.支持中文分词 2.支持多种数据源的全文检索引擎 3.分布式 4.基于lucene的 ...
- PHP笔记(PHP初级篇)
学习完HTML和CSS后,终于要开始学习PHP啦!前面的铺垫只为后路的畅顺! PHP环境搭建: 企业中常用到的环境是:Linux+Apache+MySQL+PHP 学习环境是:Windows+Apac ...
- 服务器文件上传下载(XShell+Xftp)
1.下载XShell安装包+Xftp安装包.百度网盘(XShell):https://pan.baidu.com/s/1eR4PFpS 百度网盘(Xftp):https://pan.baidu.com ...
- [Django]下拉表单与模型查询
前言:本文主要针对自定义下拉表单制作,下拉表单的内容是取至于数据库,即动态实现下拉表单 正文: 动态实现下拉表单有两种方法: 一.自己手动写 html 模板中的 <form ...> &l ...
- Java基础知识笔记(三:文件与数据流)
一.输入流与输出流 输入流将数据从文件.标准输入或其他外部输入设备中加载到内存.输出流的作用则刚好相反,即将在内存中的数据保存到文件中,或传输给输出设备.输入流在Java语言中对应于抽象类java.i ...
- vb上位机模拟电压监测系统
vb作为一种古老的语言,在工作中已经用不到了,但这门语言也是我在校期间研究比较多的一种,基本的通讯,数据库,界面等模块已经比较了解,马上要进单位实习了,研究的是电机的变频器,软件这块,希望在以后的工作 ...
- 从一个url输入浏览器到页面渲染出来,这个过程都发生了哪些事情?
经典问题:在浏览器输入一个url后,会发生什么事情呢? (1)假设是简单的http请求(GET),IPV4,无代理. 浏览器先查看浏览器缓存-系统缓存-路由器缓存,若缓存中有,请略过中间步骤,直接跳到 ...
- Linux Kernel代码艺术——系统调用宏定义
我们习惯在SI(Source Insight)中阅读Linux内核,SI会建立符号表数据库,能非常方便地跳转到变量.宏.函数等的定义处.但在处理系统调用的函数时,却会遇到一些麻烦:我们知道系统调用函数 ...