传送门

莫队基础题,适合我这种初学者。

莫队是离线算法,通常不带修改,时间复杂度为 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的项链(莫队 || 树状数组 || 主席树)的更多相关文章

  1. P1972 [SDOI2009]HH的项链[离线+树状数组/主席树/分块/模拟]

    题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链 ...

  2. zoj2112 树状数组+主席树 区间动第k大

    Dynamic Rankings Time Limit: 10000MS   Memory Limit: 32768KB   64bit IO Format: %lld & %llu Subm ...

  3. BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树

    BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树 题意: 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i, ...

  4. 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树

    题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...

  5. 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树

    题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...

  6. BZOJ_2120_数颜色_Set+树状数组+主席树

    BZOJ_2120_数颜色_Set+树状数组+主席树 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L ...

  7. P1972 [SDOI2009]HH的项链 莫队or树状数组

    用什么树状数组莫队多帅 思路:树状数组\(or\)莫队(其实还是推荐树状数组\(QwQ\)) 提交:我告诉你我卡了一会儿常 卡不满原因:没有用奇偶性排序 题解: 莫队: 就是裸的莫队,把询问排序\(e ...

  8. Bzoj 1878: [SDOI2009]HH的项链 莫队

    1878: [SDOI2009]HH的项链 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 2717  Solved: 1363[Submit][Statu ...

  9. BZOJ1878 [SDOI2009] HH的项链 [莫队,卡常]

    BZOJ传送门,洛谷传送门 HH的项链 Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一 段贝壳,思考它们所表达的含义. ...

随机推荐

  1. 题解报告:NYOJ 题目139 我排第几个(康托展开)

    描述 现在有"abcdefghijkl”12个字符,将其所有的排列中按字典序排列,给出任意一种排列,说出这个排列在所有的排列中是第几小的? 输入 第一行有一个整数n(0<n<=1 ...

  2. 用代码设置 RelativeLayout.LayoutParams

    1.注意 不能在RelativeLayout容器本身和他的子元素之间产生循环依赖,比如说,不能将RelativeLayout的高设置成为WRAP_CONTENT的时候将子元素的高设置成为 ALIGN_ ...

  3. 把List<Map<String,Object>>转成Map<String,Object>

    Map<String, Object> parmMap = new HashMap<String, Object>(); //定义一个用于存储强转后的Map List<M ...

  4. vue cli 3 打包过大问题

    vue cli 3 打包命令 npm run build,这种情况下的打包可以通过设置 vue.config.js里面的 productionSourceMap: false. 如果是自己设置的打包环 ...

  5. Angular jsonp 同源策略的问题

    引用:http://www.cnblogs.com/dengzy/p/5388357.html 说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决 ...

  6. Win7系统32位和64位的区别

    Win7系统32位和64位的区别已经是一个老话题了,可是还是有很多朋友不明白.这两者到底有什么区别呢?下面本文与大家通俗的介绍下Win7系统32位和64位的区别,其他一些深入的理论讲述,大家可以看看文 ...

  7. 【PostgreSQL-9.6.3】一般视图

    PG视图分为两种,一种是物化视图,一种是一般视图.本篇文章主要写一般视图哪些事儿.所谓一般视图,通俗点说,就是由查询语句定义的虚拟表.视图中的数据可能来自一张或多张表. 1. 视图创建语句 CREAT ...

  8. Farseer.net轻量级ORM开源框架 V1.8版本升级消息

    SHA-1: 775a93cf64df3f49c83cc4f4df346afd2075a68f * 发布V1.8.0修复:Oracle的SQL生成 在没有条件时,缺少Where关键字,导致无法分页修复 ...

  9. [转]c++应用程序文件的编译过程

    原文地址 这里讲下C++文件的编译过程及其中模板的编译过程: 一:一般的C++应用程序的编译过程.    一般说来,C++应用程序的编译过程分为三个阶段.模板也是一样的. 在cpp文件中展开inclu ...

  10. JavaScript 原生代码找对象的方法

    1. id :  document.getElementById('id') 2. 标签 : document.getElementsByTagName('标签') //获得的是一个标签数组 3. N ...