【bzoj3809/bzoj3236】Gty的二逼妹子序列/[Ahoi2013]作业 莫队算法+分块
原文地址:http://www.cnblogs.com/GXZlegend/p/6805252.html
bzoj3809
题目描述
输入
输出
对每个询问,单独输出一行,表示sl...sr中权值∈[a,b]的权值的种类数。
样例输入
10 10
4 4 5 1 4 1 5 1 2 1
5 9 1 2
3 4 7 9
4 4 2 5
2 3 4 7
5 10 4 4
3 9 1 1
1 4 5 9
8 9 3 3
2 2 1 6
8 9 1 4
样例输出
2
0
0
2
1
1
1
0
1
2
bzoj3236
题目描述
同上,只是多求了一个大小在[a,b]范围内数的个数(非数的种类数,即可以重复计算)
题解
莫队算法+分块,几乎是双倍经验
一个很显然的方法是莫队算法+树状数组,然而修改次数为n√n,修改时间为O(logn),会TLE。
由于查询次数比较少,所以可以想办法将修改时间减少,相应的增加查询时间。
这可以使用分块。
将美丽度(权值)分块,并记录每块中权值的种类数,这样在查询时只需要先找中间的块,再暴力找两边即可。
修改总时间复杂度为O(n√n*1),查询总时间复杂度为O(n*√n)。
注意查询时对两端在同一块中的特判。
对于bzoj3236,数的个数同样可以分块来求,而且相比求数的种类数更简单。
bzoj3809:
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
struct data
{
int l , r , x , y , id;
}a[1000010];
int v[100010] , cnt[100010] , num[410] , si , ans[1000010];
bool cmp(data a , data b)
{
return (a.l - 1) / si == (b.l - 1) / si ? a.r < b.r : (a.l - 1) / si < (b.l - 1) / si;
}
int main()
{
int n , m , i , j , lp = 1 , rp = 0;
scanf("%d%d" , &n , &m) , si = (int)sqrt(n);
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &v[i]);
for(i = 1 ; i <= m ; i ++ ) scanf("%d%d%d%d" , &a[i].l , &a[i].r , &a[i].x , &a[i].y) , a[i].id = i;
sort(a + 1 , a + m + 1 , cmp);
for(i = 1 ; i <= m ; i ++ )
{
while(lp > a[i].l) lp -- , num[(v[lp] - 1) / si] += (!cnt[v[lp]]) , cnt[v[lp]] ++ ;
while(rp < a[i].r) rp ++ , num[(v[rp] - 1) / si] += (!cnt[v[rp]]) , cnt[v[rp]] ++ ;
while(lp < a[i].l) cnt[v[lp]] -- , num[(v[lp] - 1) / si] -= (!cnt[v[lp]]) , lp ++ ;
while(rp > a[i].r) cnt[v[rp]] -- , num[(v[rp] - 1) / si] -= (!cnt[v[rp]]) , rp -- ;
if((a[i].x - 1) / si == (a[i].y - 1) / si)
for(j = a[i].x ; j <= a[i].y ; j ++ )
ans[a[i].id] += (cnt[j] > 0);
else
{
for(j = (a[i].x - 1) / si + 1 ; j < (a[i].y - 1) / si ; j ++ ) ans[a[i].id] += num[j];
for(j = a[i].x ; j <= ((a[i].x - 1) / si + 1) * si ; j ++ ) ans[a[i].id] += (cnt[j] > 0);
for(j = (a[i].y - 1) / si * si + 1 ; j <= a[i].y ; j ++ ) ans[a[i].id] += (cnt[j] > 0);
}
}
for(i = 1 ; i <= m ; i ++ ) printf("%d\n" , ans[i]);
return 0;
}
bzoj3236,可以看到只有极小部分改动:
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
struct data
{
int l , r , x , y , id;
}a[1000010];
int v[100010] , cnt[100010] , num[410] , sum[401] , si , ans1[1000010] , ans2[1000010];
bool cmp(data a , data b)
{
return (a.l - 1) / si == (b.l - 1) / si ? a.r < b.r : (a.l - 1) / si < (b.l - 1) / si;
}
int main()
{
int n , m , i , j , lp = 1 , rp = 0;
scanf("%d%d" , &n , &m) , si = (int)sqrt(n);
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &v[i]);
for(i = 1 ; i <= m ; i ++ ) scanf("%d%d%d%d" , &a[i].l , &a[i].r , &a[i].x , &a[i].y) , a[i].id = i;
sort(a + 1 , a + m + 1 , cmp);
for(i = 1 ; i <= m ; i ++ )
{
while(lp > a[i].l) lp -- , num[(v[lp] - 1) / si] += (!cnt[v[lp]]) , sum[(v[lp] - 1) / si] ++ , cnt[v[lp]] ++ ;
while(rp < a[i].r) rp ++ , num[(v[rp] - 1) / si] += (!cnt[v[rp]]) , sum[(v[rp] - 1) / si] ++ , cnt[v[rp]] ++ ;
while(lp < a[i].l) cnt[v[lp]] -- , num[(v[lp] - 1) / si] -= (!cnt[v[lp]]) , sum[(v[lp] - 1) / si] -- , lp ++ ;
while(rp > a[i].r) cnt[v[rp]] -- , num[(v[rp] - 1) / si] -= (!cnt[v[rp]]) , sum[(v[rp] - 1) / si] -- , rp -- ;
if((a[i].x - 1) / si == (a[i].y - 1) / si)
for(j = a[i].x ; j <= a[i].y ; j ++ )
ans1[a[i].id] += cnt[j] , ans2[a[i].id] += (cnt[j] > 0);
else
{
for(j = (a[i].x - 1) / si + 1 ; j < (a[i].y - 1) / si ; j ++ ) ans1[a[i].id] += sum[j] , ans2[a[i].id] += num[j];
for(j = a[i].x ; j <= ((a[i].x - 1) / si + 1) * si ; j ++ ) ans1[a[i].id] += cnt[j] , ans2[a[i].id] += (cnt[j] > 0);
for(j = (a[i].y - 1) / si * si + 1 ; j <= a[i].y ; j ++ ) ans1[a[i].id] += cnt[j] , ans2[a[i].id] += (cnt[j] > 0);
}
}
for(i = 1 ; i <= m ; i ++ ) printf("%d %d\n" , ans1[i] , ans2[i]);
return 0;
}
【bzoj3809/bzoj3236】Gty的二逼妹子序列/[Ahoi2013]作业 莫队算法+分块的更多相关文章
- 【BZOJ3809/3236】Gty的二逼妹子序列 [Ahoi2013]作业 莫队算法+分块
[BZOJ3809]Gty的二逼妹子序列 Description Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题. 对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b ...
- 【BZOJ-3809】Gty的二逼妹子序列 分块 + 莫队算法
3809: Gty的二逼妹子序列 Time Limit: 80 Sec Memory Limit: 28 MBSubmit: 1072 Solved: 292[Submit][Status][Di ...
- 【bzoj3809】Gty的二逼妹子序列
Description Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题. 对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数. 为了方便,我们 ...
- 【BZOJ3809】Gty的二逼妹子序列 莫队 分块
题目描述 给你一个长度为\(n\)的数列,还有\(m\)个询问,对于每个询问\((l,r,a,b)\),输出区间\([l,r]\)有多少范围在\([a,b]\)的权值. \(n\leq 100000, ...
- 莫队p2 【bzoj3809】Gty的二逼妹子序列
发现一篇已经够长了...所以就放在这里吧... http://hzwer.com/5749.html ↑依然是看大牛题解过的 袜子那道题太简单了.... 然后被这道题超时卡了一段时间....... ...
- BZOJ3809:Gty的二逼妹子序列
浅谈莫队:https://www.cnblogs.com/AKMer/p/10374756.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php?i ...
- [bzoj3809]Gty的二逼妹子序列/[bzoj3236][Ahoi2013]作业
[bzoj3809]Gty的二逼妹子序列/[bzoj3236][Ahoi2013]作业 bzoj bzoj 题目大意:一个序列,m个询问在$[l,r]$区间的$[x,y]$范围内的数的个数/种类. ...
- [bzoj3809]Gty的二逼妹子序列_莫队_分块
Gty的二逼妹子序列 bzoj-3809 题目大意:给定一个n个正整数的序列,m次询问.每次询问一个区间$l_i$到$r_i$中,权值在$a_i$到$b_i$之间的数有多少个. 注释:$1\le n\ ...
- BZOJ 3809: Gty的二逼妹子序列
3809: Gty的二逼妹子序列 Time Limit: 80 Sec Memory Limit: 28 MBSubmit: 1387 Solved: 400[Submit][Status][Di ...
随机推荐
- RDVTabBarController--可自由定制的iOS底部导航控件
RDVTabBarController:一个十分完善的tabBarController,可以自定义角标个数,爽的停不下来. RDVTabBarController地址:RDVTabBarControl ...
- Inventory Update-freecodecamp算法题目
Inventory Update 1.要求 依照一个存着新进货物的二维数组,更新存着现有库存(在 arr1 中)的二维数组. 如果货物已存在则更新数量 . 如果没有对应货物则把其加入到数组中,更新最新 ...
- BZOJ1509: [NOI2003]逃学的小孩(树的直径)
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1126 Solved: 567[Submit][Status][Discuss] Description ...
- OceanBase安装
背景: OceanBase是阿里巴巴.蚂蚁金服自主研发的可扩展的分布式关系数据库,实现了数千亿条记录.数百 TB 数据上的跨行跨表事务,主要支持支付宝核心的交易.支付.会员和账务系统等 OLTP 和 ...
- redis源代码结构解析
看了黄建宏老师的<Redis设计与实现>,对redis的部分实现有了一个简明的认识: 之前面试的时候被问到了这部分的内容,没有关注,好在还有时间,就把Redis的源码看了一遍. Redis ...
- Linux CentOS 7的图形界面安装
1.首先安装X(X Window System) yum groupinstall "X Window System" 2.由于这个软件组比较大,安装过程会比较慢,安装完成后会出现 ...
- hadoop的shuffle过程
1. shuffle: 洗牌.发牌——(核心机制:数据分区,排序,缓存): shuffle具体来说:就是将maptask输出的处理结果数据,分发给reducetask,并在分发的过程中,对数据按key ...
- Gson杂记录
//Integer userId = getUserId(); //System.out.println("userId:"+userId); /*for(int i=0;i< ...
- jira安装说明
阅读目录 1.1 jira说明 1.2 安装配置jira 1.3 web界面访问 1.4 创建第一个项目 1.5 参考文献 回到顶部 1.1 jira说明 JIRA是Atlassian公司出品的项目与 ...
- DFS:C 小Y的难题(1)
解题心得: 1.在明确使用DFS之后一定要找到递归函数的出口.方向,以及递归的点(在某个情况下开始递归)(void 也可以return,但是没有返回值).递归时也要有递归的方向,最后都能够达到递归的出 ...