洛谷 P1972 BZOJ 1878 [SDOI2009]HH的项链
题目描述
HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH 不断地收集新的贝壳,因此,他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答……因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。
输入输出格式
输入格式:
第一行:一个整数N,表示项链的长度。
第二行:N 个整数,表示依次表示项链中贝壳的编号(编号为0 到1000000 之间的整数)。
第三行:一个整数M,表示HH 询问的个数。
接下来M 行:每行两个整数,L 和R(1 ≤ L ≤ R ≤ N),表示询问的区间。
输出格式:
M 行,每行一个整数,依次表示询问对应的答案。
输入输出样例
6
1 2 3 4 3 5
3
1 2
3 5
2 6
2
2
4
说明
数据范围:
对于100%的数据,N <= 50000,M <= 200000。
解题思路
在线解法听说可以用主席树?那玩意太高端,本蒟蒻不会……2019年7月30日21:10:59更新,现在会了HDU 5919 Sequence ll
离线解法主要有两种——一种是求区间和的奇技淫巧,另一种是分块莫队。我用的是前一种。
单点修改求区间和的方法挺多,这里用的树状数组(方便、简单)
离线,先把所有询问存下来,然后对所有询问按照左端点升序排序(右端点排不排无所谓的啦,反正又不影响结果)。
然后记录下每种颜色的下一个相同颜色所在的位置,用next[i]表示。
然后在树状数组(开始时全部是0)中把每种颜色第一次出现的位置标记为1,然后就可以按排好的顺序处理所有询问了。
一个个询问可以看作是一个滑动窗口在项链上滑动,读取窗口内的颜色信息。
窗口向右移动以后,左端点的左边那些第一次出现的颜色在窗口中就表示不出来了,这时就要把左端点以左的标记为1颜色全部“弄”到下一个颜色相同的点上(next[i])。
定义一个变量$l$,然后按之前的左端点递增的顺序处理询问。
让$l$从1开始不断增加,直到到达第$i$个询问所要求的左端点前一位,这部分的作用是把当前询问区间的左边那些1全部“弄”到后面。然后统计这次询问的答案,线段树求这个询问区间的区间和就是答案啦!
----------------------------------------------------分割线-------------------------------------------------------
2019年03月02日16:57:57。我当年写的啥玩意……丢个我现在看得懂的链接。为啥我的代码比黄学长长那么多……2019年03月02日17:09:23把上面的描述更新了一波,好像好懂多了(说不定一年多以后我又看不懂了)。
----------------------------------------------------分割线-------------------------------------------------------
我来填坑啦!并不会输公式,勉强看看吧
莫队离线处理询问区间(li,ri),如果知道了(li,ri)的答案,那我们就能很快知道(li-1,ri)(li+1,ri)(li,ri-1)(li,ri+1)的答案,那么在已知(l[i],r[i])的答案的情况下,我们需要O(abs(l[i]-l[i+1])+abs(r[i]-r[i+1]))的时间暴力得到(l[i+1],r[i+1])的答案。如何使转移代价最少?一种方法是按曼哈顿最小生成树的dfs序转移,但是难度过高,于是——
对于每个读入的询问(l[i],r[i]),我们设pos[i]=l[i]/sqrt(n),(这就是传说中的分块)以pos[i]为第一关键字,r[i]为第二关键字对所有询问进行排序,依次处理询问,这样能跑得很快。时间复杂度变成了O(n^(3/2))。
证明和代码网上遍地都是,这里就不贴了(逃)。下面的代码思路是树状数组的。
源代码
#include<cstdio>
#include<algorithm>
#define lowbit(x) (x)&(-x) int n,m,mx=-;
int a[]={},next[]={};
int p[]={};//类似一个桶,装每种颜色第一次出现的位置 int c[]={};//树状数组
int query(int pos)
{
int ans=;
while(pos)
{
ans+=c[pos];
pos-=lowbit(pos);
}
return ans;
}
void add(int pos,int x)
{
while(pos<=n)
{
c[pos]+=x;
pos+=lowbit(pos);
}
} struct Ask{
int l,r,id,ans;
}ask[];
bool cmp1(const Ask & a,const Ask & b)
{
return a.l==b.l?a.r<b.r:a.l<b.l;
}
bool cmp2(const Ask & a,const Ask & b)
{
return a.id<b.id;
} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",a+i),mx=std::max(a[i],mx);
for(int i=n;i>;i--)//预处理出next和p
{
next[i]=p[a[i]];
p[a[i]]=i;
}
for(int i=;i<=mx;i++) if(p[i])add(p[i],); scanf("%d",&m);
for(int i=,l,r;i<=m;i++)
{
scanf("%d%d",&l,&r);
ask[i]={l,r,i,};
} std::stable_sort(ask+,ask++m,cmp1);
//用归并的原因是,apio2017,第二题交互题,某部分分可以用stl排序的比较函数发出询问,然后就能得到结果。 这个页面三分之二的位置
//询问次数有限,用归并才能以较少的比较函数调用次数卡过去,好些大佬就这样被卡了85。当时半懂不懂的,apio以后用了好久归并,不敢用快排#捂脸
for(int i=,ll=;i<=m;i++)
{
while(ll<ask[i].l)
{
if(next[ll]) add(next[ll],);
ll++;
}
ask[i].ans=query(ask[i].r)-query(ask[i].l-);
} std::stable_sort(ask+,ask++m,cmp2);
for(int i=;i<=m;i++)
printf("%d\n",ask[i].ans); return ;
}
洛谷 P1972 BZOJ 1878 [SDOI2009]HH的项链的更多相关文章
- BZOJ 1878: [SDOI2009]HH的项链
1878: [SDOI2009]HH的项链 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 3548 Solved: 1757[Submit][Statu ...
- BZOJ 1878: [SDOI2009]HH的项链 离线树状数组
1878: [SDOI2009]HH的项链 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
- Bzoj 1878: [SDOI2009]HH的项链 莫队
1878: [SDOI2009]HH的项链 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 2717 Solved: 1363[Submit][Statu ...
- BZOJ 1878: [SDOI2009]HH的项链( BIT )
离线处理 , 记下询问的左右端点并排序 , 然后可以利用树状数组 , 保证查询区间时每种颜色只计算一次 ------------------------------------------------ ...
- BZOJ 1878 [SDOI2009]HH的项链 【莫队】
任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=1878 1878: [SDOI2009]HH的项链 Time Limit: 4 Sec M ...
- 【洛谷】1972:[SDOI2009]HH的项链【莫队+树状数组】
P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...
- BZOJ 1878 [SDOI2009]HH的项链 (主席树 或 莫队算法)
题目链接 HH的项链 这道题可以直接上主席树的模板 #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) ...
- bzoj 1878 [SDOI2009]HH的项链(离线处理+BIT)
Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此, 他的项链变 ...
- bzoj 1878: [SDOI2009]HH的项链 ——树状数组+ 差分
Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一 段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此他的项链变得 ...
随机推荐
- 【BZOJ 3032】 七夕祭
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=3032 [算法] 交换左右两个相邻格子的摊点,不会改变这一行的摊点个数 交换上下两个相 ...
- B2242 [SDOI2011]计算器
这个题就是把三个数论基础合在了一起,算是一道比较全面的题. 1的时候就是快速幂 2的时候是exgcd求逆元,特殊的,只有两数互质才有逆元. 3就是bsgs啦,还是不太熟 题干: Description ...
- bzoj4889
http://www.lydsy.com/JudgeOnline/problem.php?id=4889 人傻常数大 bzoj上跑不过 洛谷上能过两到三个点 我写的是树套树啊 怎么跑的比分块还慢 每次 ...
- [Swift通天遁地]二、表格表单-(13)实时调整表单元素的显示和隐藏
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- [Swift通天遁地]四、网络和线程-(4)使用Alamofire实现网络请求
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- TypeScript `unknown` 类型
unknown 字面理解和 any 其实没差,任何类型都可赋值给它,但有一点, Anything is assignable to unknown, but unknown isn't assigna ...
- HTML-ul分分钟理解
在HTML中,列表有三种,如图分别是有序.无序和自定义列表.上面是我在网络上找到的一张图片很明了就看以看出来,今天要分享的就是其中的无序列表Ul(unordered list),给大家整理了一下我所知 ...
- Salvation -- ---广搜 + 限定方向 ,
这个欣求 , 在迷宫里密室了方向 , 走过了一个地方 不做标记 还一个劲 , 找不到媳妇不亏 . 这个题 我跳了两个坑 , 1 : 习惯性添加标记走过的 位置 ,导致所有的位置都能 走过一遍 , ...
- 【BZOJ4025】二分图(可撤销并查集+线段树分治)
题目: BZOJ4025 分析: 定理:一个图是二分图的充要条件是不存在奇环. 先考虑一个弱化的问题:保证所有边出现的时间段不会交叉,只会包含或相离. 还是不会?再考虑一个更弱化的问题:边只会出现不会 ...
- Python安装distribute包
从官网https://pypi.python.org/pypi/distribute/0.6.49#downloads上下载distribute包,解压后进入解压文件的目录下,使用 python se ...