P4396 [AHOI2013]作业 分块+莫队
这个题正解是莫队+树状数组,但是我个人非常不喜欢树状数组这种东西,所以决定用分块来水这个题。直接在莫队维护信息的时候,维护单点同时维护块内信息就行了。
莫队就是这几行核心代码:
void add(int x)
{
++f[bl[x]];//维护块
++cnt[x];//维护点
if(cnt[x] == )
g[bl[x]]++;
}
void del(int x)
{
--f[bl[x]];
--cnt[x];
if(!cnt[x])
g[bl[x]]--;
}
void moqueue()
{
int l = ,r = ;
duke(i,,m)
{
while(l > G[i].l) add(s[--l]);
while(l < G[i].l) del(s[l++]);
while(r < G[i].r) add(s[++r]);
while(r > G[i].r) del(s[r--]);
work(G[i].a,G[i].b,i);
}
}
剩下就是暴力了,说真的,这个作法真的暴力,但是就是能过。哈哈哈。
题干:
题目描述 此时己是凌晨两点,刚刚做了Codeforces的小A掏出了英语试卷。英语作业其实不算多,一个小时刚好可以做完。然后是一个小时可以做完的数学作业,接下来是分别都是一个小时可以做完的化学,物理,语文......小A压力巨大。 这是小A碰见了一道非常恶心的数学题,给定了一个长度为n的数列和若干个询问,每个询问是关于数列的区间表示数列的第1个数到第r个数),首先你要统计该区间内大于等于a,小于等于b的数的个数,其次是所有大于等于a,小于等于b的,且在该区间中出现过的数值的个数。 小A望着那数万的数据规模几乎绝望,只能向大神您求救,请您帮帮他吧。
输入输出格式
输入格式: 第一行n,m 接下来n个数表示数列 接下来m行,每行四个数l,r,a,b 输出格式: 输出m行,分别对应每个询问,输出两个数,分别为在1到i?这段区间中大小在[a,b]中的数的个数,以及大于等于a,小于等于b的,且在该区间中出现过的数值的个数(具体可以参考样例)。 输入输出样例
输入样例#: 复制 输出样例#: 复制 说明 N<=,M<=
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(int i = a;i <= n;i++)
#define lv(i,a,n) for(int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
const int INF = << ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
const int N=;
struct edge{
int l,r,a,b;
int ans1,ans2;
int id;
}G[N];
int cnt[N];
int bl[N];
int blk;
int n,m;
int s[N];
int f[N],g[N];
bool cmp(edge x,edge y)
{
if(bl[x.l] != bl[y.l])
return bl[x.l] < bl[y.l];
else
return x.r < y.r;
}
void add(int x)
{
++f[bl[x]];
++cnt[x];
if(cnt[x] == )
g[bl[x]]++;
}
void del(int x)
{
--f[bl[x]];
--cnt[x];
if(!cnt[x])
g[bl[x]]--;
}
void work(int l,int r,int x)
{
if(bl[l] == bl[r])
{
duke(i,l,r)
{
if(cnt[i])
G[x].ans1 += cnt[i],G[x].ans2 ++;
}
}
else
{
lv(i,bl[l] * blk - ,l)
if(cnt[i])
G[x].ans1 += cnt[i],G[x].ans2 ++;
duke(i,bl[r] * blk - blk,r)
if(cnt[i])
G[x].ans1 += cnt[i],G[x].ans2 ++;
duke(i,bl[l] + ,bl[r] - )
G[x].ans1 += f[i],G[x].ans2 += g[i];
}
}
void moqueue()
{
int l = ,r = ;
duke(i,,m)
{
while(l > G[i].l) add(s[--l]);
while(l < G[i].l) del(s[l++]);
while(r < G[i].r) add(s[++r]);
while(r > G[i].r) del(s[r--]);
work(G[i].a,G[i].b,i);
}
}
bool cmp2(edge a,edge b)
{
return a.id < b.id;
}
int main()
{
read(n);read(m);
duke(i,,n)
read(s[i]);
blk = sqrt(n);
duke(i,,m)
bl[i] = (i) / blk + ;
duke(i,,m)
{
read(G[i].l);read(G[i].r);
read(G[i].a);read(G[i].b);
G[i].id = i;
}
sort(G + ,G + m + ,cmp);
moqueue();
sort(G + ,G + m + ,cmp2);
duke(i,,m)
{
printf("%d %d\n",G[i].ans1,G[i].ans2);
}
return ;
}
/*
3 4
1 2 2
1 2 1 3
1 2 1 1
1 3 1 3
2 3 2 3
*/
代码:
P4396 [AHOI2013]作业 分块+莫队的更多相关文章
- BZOJ_3809_Gty的二逼妹子序列 && BZOJ_3236_[Ahoi2013]作业 _莫队+分块
BZOJ_3809_Gty的二逼妹子序列 && BZOJ_3236_[Ahoi2013]作业 _莫队+分块 Description Autumn和Bakser又在研究Gty的妹子序列了 ...
- 【Luogu4396】[AHOI2013]作业(莫队)
[Luogu4396][AHOI2013]作业(莫队) 题面 洛谷 题解 模板题 #include<iostream> #include<cstdio> #include< ...
- [BZOJ3236]:[Ahoi2013]作业(莫队+分块)
题目传送门 题目描述 此时已是凌晨两点,刚刚做了$Codeforces$的小$A$掏出了英语试卷.英语作业其实不算多,一个小时刚好可以做完.然后是一个小时可与做完的数学作业,接下来是分别都是一个小时可 ...
- 【洛谷4396/BZOJ3236】[AHOI2013]作业(莫队+分块/树状数组/线段树)
题目: 洛谷4396 BZOJ3236(权限) 这题似乎BZOJ上数据强一些? 分析: 这题真的是--一言难尽 发现题面里没说权值的范围,怕出锅就写了离散化.后来经过面向数据编程(以及膜神犇代码)知道 ...
- BZOJ3236 [Ahoi2013]作业 【莫队 + 树状数组】
题目链接 BZOJ3236 题解 没想到这题真的是如此暴力 #include<algorithm> #include<iostream> #include<cstring ...
- 【BZOJ-3809】Gty的二逼妹子序列 分块 + 莫队算法
3809: Gty的二逼妹子序列 Time Limit: 80 Sec Memory Limit: 28 MBSubmit: 1072 Solved: 292[Submit][Status][Di ...
- 2018.11.07 NOIP训练 L的鞋子(权值分块+莫队)
传送门 乱搞题. 我直接对权值分块+莫队水过了. 不过调了30min30min30min发现ststst表挂了是真的不想说什么233. 代码
- HDU 5145 分块 莫队
给定n个数,q个询问[l,r]区间,每次询问该区间的全排列多少种. 数值都是30000规模 首先考虑计算全排列,由于有同种元素存在,相当于每次在len=r-l+1长度的空格随意放入某种元素即$\bin ...
- bzoj 3585 mex - 线段树 - 分块 - 莫队算法
Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问 ...
随机推荐
- 【Oracle】RedHat 6.5 安装 11gR2数据库
1. 挂载操作系统光盘 [root@drz ~]# mount /dev/cdrom /mnt mount: block device /dev/sr0 is write-protected, mou ...
- 用js制作一个计算器
使用js制作计算器 <!doctype html> <html lang="en"> <head> <meta charset=" ...
- JavaScript函数和window对象
一.什么是函数 函数的含义:类似于Java中的方法,是完成特定任务的代码语句块 使用更简单:不用定义属于某个类,直接使用 二.常用系统函数 parseInt ("字符串") ...
- WinDbg使用
1.抓dump文件 程序崩溃(crash)的时候, 为了以后能够调试分析问题, 可以使用WinDBG要把当时程序内存空间数据都保存下来,生成的文件称为dump 文件. 步骤: 1) 打开WinDBG并 ...
- 设计包含min()函数的栈
题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素.要求函数min.push以及pop的时间复杂度都是O(1). 分析:这是去年google的一道面试题. 我看到这道题目时,第一反应 ...
- 参加EMCL感想
ECML,全名为欧洲机器学习会议,European Conference on Machine Learning 原文链接:http://blog.sina.com.cn/s/blog_59388e2 ...
- 11.02 跳过表中n行
select x.enamefrom (select a.ename,(select count(*)from emp bwhere b.ename <=a.ename) as rnfrom e ...
- VCSA服务重启命令
Sphere Web Client界面的服务分别是: vmware-mbcs vmware-netdumper vmware-rbd-watchdog 分别执行命令确认,首先执行命令: service ...
- C++ 资源大全中文版
标准库 C++标准库,包括了STL容器,算法和函数等. C++ Standard Library:是一系列类和函数的集合,使用核心语言编写,也是C++ISO自身标准的一部分. Standard Tem ...
- tree:以树形结构显示目录下的内容
tree命令 1.命令详解 [功能说明] tree命令的中文意思为“树”,功能是以树形结构列出指定目录下的所有内容包括所有文件.子目录及子目录里的目录和文件. [语法格式] tree [option] ...