[luoguP1972] [SDOI2009]HH的项链(莫队 || 树状数组 || 主席树)
莫队基础题,适合我这种初学者。
莫队是离线算法,通常不带修改,时间复杂度为 O(n√n)
我们要先保证通过 [ l , r ] 求得 [ l , r + 1 ] , [ l , r - 1 ] , [ l - 1 , r ] , [ l + 1 , r ] 的效率是O(1)的
对于莫队的理解,移步远航休息栈
——代码
#include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm> int n, m, S, ans = ;
int a[], ton[], anslist[];
struct node
{
int l, r, id, num;
}q[]; inline int read()
{
int x = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar());
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x;
} inline bool cmp(node x, node y)
{
return x.id ^ y.id ? x.id < y.id : x.r < y.r;
} int main()
{
int i, x, y;
n = read();
for(i = ; i <= n; i++) a[i] = read();
m = read();
for(i = ; i <= m; i++) q[i].l = read(), q[i].r = read(), q[i].num = i;
S = sqrt(n);
for(i = ; i <= m; i++) q[i].id = q[i].l / S + ;
std::sort(q + , q + m + , cmp);
x = q[].l, y = q[].l;
ton[a[x]]++;
for(i = ; i <= m; i++)
{
while(x < q[i].l)
{
ton[a[x]]--;
if(!ton[a[x]]) ans--;
x++;
}
while(x > q[i].l)
{
x--;
if(!ton[a[x]]) ans++;
ton[a[x]]++;
}
while(y > q[i].r)
{
ton[a[y]]--;
if(!ton[a[y]]) ans--;
y--;
}
while(y < q[i].r)
{
y++;
if(!ton[a[y]]) ans++;
ton[a[y]]++;
}
anslist[q[i].num] = ans;
}
for(i = ; i <= m; i++) printf("%d\n", anslist[i]);
return ;
}
代码量真是友善啊
还可以用离线用树状数组来做.
以下是hzwer的解法:
这题首先在线是没法做的,所以我们可以考虑离线算法
首先记录下每种颜色的下一种颜色所在的位置
将所有询问按照左端点进行排序
将所有颜色的第一个点x a[x]++
然后从左往右扫
扫到一个点x将a[next[x]]++
碰到一个询问l,r输出sum[r]-sum[l-1]
其中sum是a数组的前缀和
求前缀和可以用树状数组
——代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> const int MAXN = ;
int n, m, max;
int head[MAXN], next[MAXN], a[MAXN], ans[MAXN], c[];
struct node
{
int l, r, id;
}q[MAXN]; inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline int Max(int x, int y)
{
return x > y ? x : y;
} inline void update(int x)
{
for(; x <= n; x += x & -x) c[x]++;
} inline int query(int x)
{
int ret = ;
for(; x; x -= x & -x) ret += c[x];
return ret;
} inline bool cmp(node x, node y)
{
return x.l < y.l;
} int main()
{
int i, j;
n = read();
memset(head, -, sizeof(head));
for(i = ; i <= n; i++) a[i] = read(), max = Max(max, a[i]);
for(i = n; i; i--) next[i] = head[a[i]], head[a[i]] = i;
for(i = ; i <= max; i++)
if(head[i] ^ -)
update(head[i]);
m = read();
for(i = ; i <= m; i++)
{
q[i].l = read();
q[i].r = read();
q[i].id = i;
}
std::sort(q + , q + m + , cmp);
j = ;
for(i = ; i <= n; i++)
{
while(q[j].l == i) ans[q[j].id] = query(q[j].r) - query(q[j].l - ), j++;
if(next[i] ^ -) update(next[i]);
}
for(i = ; i <= m; i++) printf("%d\n", ans[i]);
return ;
}
主席树也是个好方法。
保存每个点的上一个和它颜色相同的点的位置(如果没有就是0)
然后以每个点的前驱为下标建主席数。
统计时只需要统计当前区间 [x,y] 中前驱小于 x 的点的个数
——代码
#include <cstdio>
#include <iostream> const int MAXN = ;
int n, m, cnt;
int a[MAXN], head[], pre[MAXN], root[MAXN], sum[MAXN * ], ls[MAXN * ], rs[MAXN * ]; inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline void update(int &now, int l, int r, int x)
{
++cnt;
sum[cnt] = sum[now] + ;
ls[cnt] = ls[now];
rs[cnt] = rs[now];
now = cnt;
if(l == r) return;
int mid = (l + r) >> ;
if(x <= mid) update(ls[now], l, mid, x);
else update(rs[now], mid + , r, x);
} inline int query(int x, int y, int l, int r, int k)
{
if(l == r) return sum[y] - sum[x];
int mid = (l + r) >> ;
if(k <= mid) return query(ls[x], ls[y], l, mid, k);
else return query(rs[x], rs[y], mid + , r, k) + sum[ls[y]] - sum[ls[x]];
} int main()
{
int i, x, y;
n = read();
for(i = ; i <= n; i++)
{
a[i] = read();
pre[i] = head[a[i]];
head[a[i]] = i;
}
for(i = ; i <= n; i++)
{
root[i] = root[i - ];
update(root[i], , n, pre[i]);
}
m = read();
for(i = ; i <= m; i++)
{
x = read();
y = read();
printf("%d\n", query(root[x - ], root[y], , n, x - ));
}
return ;
}
[luoguP1972] [SDOI2009]HH的项链(莫队 || 树状数组 || 主席树)的更多相关文章
- P1972 [SDOI2009]HH的项链[离线+树状数组/主席树/分块/模拟]
题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链 ...
- zoj2112 树状数组+主席树 区间动第k大
Dynamic Rankings Time Limit: 10000MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu Subm ...
- BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树
BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树 题意: 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i, ...
- 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树
题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...
- 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树
题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...
- BZOJ_2120_数颜色_Set+树状数组+主席树
BZOJ_2120_数颜色_Set+树状数组+主席树 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L ...
- P1972 [SDOI2009]HH的项链 莫队or树状数组
用什么树状数组莫队多帅 思路:树状数组\(or\)莫队(其实还是推荐树状数组\(QwQ\)) 提交:我告诉你我卡了一会儿常 卡不满原因:没有用奇偶性排序 题解: 莫队: 就是裸的莫队,把询问排序\(e ...
- Bzoj 1878: [SDOI2009]HH的项链 莫队
1878: [SDOI2009]HH的项链 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 2717 Solved: 1363[Submit][Statu ...
- BZOJ1878 [SDOI2009] HH的项链 [莫队,卡常]
BZOJ传送门,洛谷传送门 HH的项链 Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一 段贝壳,思考它们所表达的含义. ...
随机推荐
- uwp选取文件夹并读取其中的图片
uwp对文件的操作和wpf,winform等等有很大的不同,主要原因是uwp对权限的要求比较严格,不能想从前那样随心所欲的读取文件. 1.首先找到Package.appxmanifest这个文件,在功 ...
- hbase源码分析:ERROR: Table already exists问题诊断
问题描述: 重新安装了测试环境的hadoop,所以之前hbase所建的表数据都丢失了,但是zookeeper没有动.在hbase shell中list的时候,看不到之前建的表,但是create tes ...
- Radis
http://www.redis.cn/ http://try.redis.io/ http://www.redisdoc.com/en/latest/ Redis 命令参考¶ 本文档是 Redis ...
- ReactJS-0-React介绍
React介绍: React是一个库而不是一个MVC框架,因为React只负责解决MVC框架中V(View)层面的问题,React致力于创建可重用的UI组件.(React is a library f ...
- Android图片压缩,不失真,上线项目
当然了,图片压缩是利用了libjpeg库的基础上,牛逼的同学可以自行生成so.jar.在此给出一个链接: http://www.cnblogs.com/hrlnw/p/4403334.html 在生成 ...
- vue2.0 v-model指令
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- vscode前端开发软件配搭好用的插件
使用方法,可以在官网中搜索需要的插件或者在VsCode的“”扩展“”中搜索需要的插件添加方法使用Ctrl+P, 输入 ext install xxxx ,搜索要安装的插件,点击安装按钮即可(各取所需插 ...
- java web 学习笔记 - JSP标签编程
1.JSP标签编程简介 标签编程在开发中并不常见,主要是为了更好的理解struts等框架的标签而打基础,完善相关知识体系. 标签编程分为: 一个继承自TagSupport的标签类,一个在WEB-INF ...
- Dynamic type checking and runtime type information
动态类型的关键是将动态对象与实际类型信息绑定. See also: Dynamic programming language and Interpreted language Dynamic type ...
- app dcloud 打包公用证书
Android平台云端打包使用的DCloud公用证书 分类:HTML5+ 5+App开发 HBuilder|HBuilderX应用云端打包Android平台默认使用的DCloud公用证书,其信息如下: ...