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个数. 从第三行开始,每行一个询问 ...
随机推荐
- 网上找的JS截取字符串(含中文)
<script> /* 2007-11-28 XuJian */ //截取字符串 包含中文处理 //(串,长度,增加...) function subString(str, len, ha ...
- 【技术累积】【点】【java】【18】URLEncode
基础概念 由于以URL的形式传递信息给服务器时,不允许URL中出现一些特殊字符和空格的,所以需要对URL进行编码处理. 原理是: 将要转码的字符转变为16进制: 从右到左,每两位前面加% 哪些字符是需 ...
- ASP.NET MVC5 网站开发实践(一)
一.开发环境 1.开发环境: Visual Studio 2013 2.数据库:Sql Server 2012 3.代码管理:TFS(微软免费提供的) 说明:VS2013与vs2012感觉变化不大,我 ...
- Generics of a Higher Kind
http://adriaanm.github.io/files/higher.pdf https://www.atlassian.com/blog/archives/scala-types-of-a- ...
- [系统资源攻略]IO第一篇-磁盘IO,内核IO概念
几个基本的概念 在研究磁盘性能之前我们必须先了解磁盘的结构,以及工作原理.不过在这里就不再重复说明了,关系硬盘结构和工作原理的信息可以参考维基百科上面的相关词条--Hard disk drive(英文 ...
- Java 8 集合不完全一览
JDK 8 List 名称 线程安全 数据结构 允许 null 默认初始容量 扩容策略 备注 ArrayList 不安全 数组 允许 10 1.5 * old LinkedList 不安全 双链表 允 ...
- Linux思维导图之inode、mv、cp和硬软链接
标准I / O和管道: ps aux进程管理命令(和win任务管理器一样); 当前命令行输出窗口,键盘的输入即是标准输入.标准输出就是执行了的命令,无法执行的命令或错误信息是标准错误, ...
- mysql查询表里的重复数据
先贴个简单的SQL语句 select username,count(*) as count from hk_test group by username having count>1; 使用详情 ...
- 重装系统后导入raid
参考 https://ubuntuforums.org/showthread.php?t=2002217 https://www.funkypenguin.co.nz/note/importing-e ...
- 数位dp题集
题集见大佬博客 不要62 入门题,检验刚才自己有没有看懂 注意一些细节. 的确挺套路的 #include<bits/stdc++.h> #define REP(i, a, b) for(r ...