传送门

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

莫队是离线算法,通常不带修改,时间复杂度为 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. 通过Fiddler监控Java应用发送请求及相应数据

    Fiddler可以很好的监控浏览器发送的各种请求及响应数据,对于JAVA程序默认情况下是无法监控的,但实际需求中需要监控JAVA程序发送HTTP请求及返回数据是否正确. Fiddler默认配置的监听端 ...

  2. PWA之serviceWorker应用

    1.serviceWorker介绍service worker是一段运行在浏览器后台的JavaScript脚本,在页面中注册并安装成功后,它可以拦截和处理网络请求,实现缓存资源并可在离线时响应用户的请 ...

  3. 每天学点linux命令之locate 与 find 命令

    定位某个文件的位置 方法一 sudo find / -name libGLEW.so.1.13 -type f 方法二 sudo updatedb && locate libopenc ...

  4. 有关LD_LIBRARY_PATH与ld.so.conf

    我之前写过一篇关于LD_LIBRARY_PATH与gcc/g++ -L的关系的文章,于是我自己用CPACK制作了一个Debian安装包,然后我在/home/.bashrc里添加了export LD_L ...

  5. [转]C#Linq中的Union All/Union/Intersect和Top/Bottom和Paging和SqlMethods,skip,take,takewhile,skipwhile,编译查询等

    本文转自:http://www.cnblogs.com/suizhikuo/p/3791799.html 我们继续讲解LINQ to SQL语句,这篇我们来讨论Union All/Union/Inte ...

  6. Oracle函数大全下载

    Oracle函数大全下载 是一个压缩包,里面是一个chm格式的帮助文档,很实用.

  7. C#_JDBC连接数据库

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. 归并排序算法及其JS实现

    归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(con ...

  9. SCANF输入错误

    while((a<=0||a>=10)||(b<=0||b>=10))    {        fflush(stdin);        cout<<" ...

  10. Android学习笔记(十一) Intent

    一.Intent对象的基本概念 -Intent是Android应用程序组件之一 -Intent对象在Android系统当中表示一种意图 -Intent当中最重要的内容是action与data 二.In ...