HH的项链 HYSBZ - 1878 (莫队/ 树状数组)
HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一
段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此他的项链变得越来越长。有一天,他突然提出了一
个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答。。。因为项链实在是太长了。于是,他只
好求助睿智的你,来解决这个问题。
Input
第一行:一个整数N,表示项链的长度。
第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的整数)。
第三行:一个整数M,表示HH询问的个数。
接下来M行:每行两个整数,L和R(1 ≤ L ≤ R ≤ N),表示询问的区间。
N ≤ 50000,M ≤ 200000。
Output
M行,每行一个整数,依次表示询问对应的答案。
Sample Input
6 1 2 3 4 3 5 3 1 2 3 5 2 6
Sample Output
2 2 4
Hint
思路:
1、用莫队的话就是一个模板题。
2、 用离线树状数组的话,将询问区间按照L升序排序,然后对数组中,每一个数a[i] 记录一个 Next [i] 代表这个数右边再一次出现的下标。
然后维护一个当前下标L =1 开始,更新树状数组即可。
莫队的代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2) { ans = ans * a % MOD; } a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int *p);
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
ll ans[maxn];
ll Ans = 0ll;
int l = 0;
int r = 0;
int b[maxn];
int vis[maxn];
struct node {
int l, r, id;
} a[maxn];
int pos[maxn];
int n, m;
int len;
bool cmp(node aa, node bb)
{
if (pos[aa.l] == pos[bb.l]) {
return aa.r < bb.r;
} else {
return pos[aa.l] < pos[bb.l];
}
}
void add(int x)
{
if (!vis[x]) {
Ans++;
}
vis[x]++;
}
void del(int x)
{
if (vis[x] == 1) {
Ans--;
}
vis[x]--;
}
int main()
{
//freopen("D:\\code\\text\\input.txt","r",stdin);
//freopen("D:\\code\\text\\output.txt","w",stdout);
gg(n);
len = (int)(sqrt(n));
repd(i, 1, n) {
gg(b[i]);
}
gg(m);
repd(i, 1, m) {
gg(a[i].l);
gg(a[i].r);
a[i].id = i;
pos[i] = i / len;
}
sort(a + 1, a + 1 + m, cmp);
repd(i, 1, m) {
while (l > a[i].l) {
l--;
add(b[l]);
}
while (r < a[i].r) {
r++;
add(b[r]);
}
while (l < a[i].l) {
del(b[l]);
l++;
}
while (r > a[i].r) {
del(b[r]);
r--;
}
ans[a[i].id] = Ans;
}
repd(i, 1, m) {
printf("%lld\n", ans[i]);
}
return 0;
}
inline void getInt(int *p)
{
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
} else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}
树桩数组的代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2) { ans = ans * a % MOD; } a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int *p);
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int tree[maxn];
int lowbit(int x)
{
return -x & x;
}
int n, m;
void add(int x, int val)
{
while (x <= n) {
tree[x] += val;
x += lowbit(x);
}
}
int ask(int x)
{
int res = 0;
while (x) {
res += tree[x];
x -= lowbit(x);
}
return res;
}
struct node {
int l, r, ans, id;
} b[maxn];
bool cmp1(node aa, node bb)
{
if (aa.l != bb.l) {
return aa.l < bb.l;
} else {
return aa.l < bb.l;
}
}
bool cmp2(node aa, node bb)
{
return aa.id < bb.id;
}
int a[maxn];
int mx = -1;
int Next[maxn];
int pos[maxn];
int main()
{
//freopen("D:\\code\\text\\input.txt","r",stdin);
//freopen("D:\\code\\text\\output.txt","w",stdout);
gbtb;
cin >> n;
repd(i, 1, n) {
cin >> a[i];
}
for (int i = n; i >= 1; i--) {
Next[i] = pos[a[i]];
pos[a[i]] = i;
mx = max(mx, a[i]);
}
for (int i = 0; i <= mx; ++i) {
if (pos[i]) {
add(pos[i], 1);
}
}
cin >> m;
repd(i, 1, m) {
cin >> b[i].l >> b[i].r;
b[i].id = i;
}
sort(b + 1, b + 1 + m, cmp1);
int l = 1;
repd(i, 1, m) {
while (l < b[i].l) {
if (Next[l]) {
add(Next[l], 1);
// add(l, -1);可有可无。
}
l++;
}
b[i].ans = ask(b[i].r) - ask(b[i].l - 1);
}
sort(b + 1, b + 1 + m, cmp2);
repd(i, 1, m) {
printf("%d\n", b[i].ans );
}
return 0;
}
inline void getInt(int *p)
{
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
} else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}
HH的项链 HYSBZ - 1878 (莫队/ 树状数组)的更多相关文章
- bzoj3236 作业 莫队+树状数组
莫队+树状数组 #include<cstdio> #include<cstring> #include<iostream> #include<algorith ...
- BZOJ_3289_Mato的文件管理_莫队+树状数组
BZOJ_3289_Mato的文件管理_莫队+树状数组 Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号 .为了防止他人 ...
- BZOJ3236[Ahoi2013]作业——莫队+树状数组/莫队+分块
题目描述 输入 输出 样例输入 3 4 1 2 2 1 2 1 3 1 2 1 1 1 3 1 3 2 3 2 3 样例输出 2 2 1 1 3 2 2 1 提示 N=100000,M=1000000 ...
- COGS.1822.[AHOI2013]作业(莫队 树状数组/分块)
题目链接: COGS.BZOJ3236 Upd: 树状数组实现的是单点加 区间求和,采用值域分块可以\(O(1)\)修改\(O(sqrt(n))\)查询.同BZOJ3809. 莫队为\(O(n^{1. ...
- bzoj 3289: Mato的文件管理 莫队+树状数组
3289: Mato的文件管理 Time Limit: 40 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description Mato同学 ...
- 51nod 1290 Counting Diff Pairs | 莫队 树状数组
51nod 1290 Counting Diff Pairs | 莫队 树状数组 题面 一个长度为N的正整数数组A,给出一个数K以及Q个查询,每个查询包含2个数l和r,对于每个查询输出从A[i]到A[ ...
- 【BZOJ3460】Jc的宿舍(树上莫队+树状数组)
点此看题面 大致题意: 一棵树,每个节点有一个人,他打水需要\(T_i\)的时间,每次询问两点之间所有人去打水的最小等待时间. 伪·强制在线 这题看似强制在线,但实际上,\(pre\ mod\ 2\) ...
- HihoCoder 1488 : 排队接水(莫队+树状数组)
描述 有n个小朋友需要接水,其中第i个小朋友接水需要ai分钟. 由于水龙头有限,小Hi需要知道如果为第l个到第r个小朋友分配一个水龙头,如何安排他们的接水顺序才能使得他们等待加接水的时间总和最小. 小 ...
- BZOJ 3236 莫队+树状数组
思路: 莫队+树状数组 (据说此题卡常数) yzy写了一天(偷笑) 复杂度有点儿爆炸 O(msqrt(n)logn) //By SiriusRen #include <cmath> #in ...
- BZOJ 3236: [Ahoi2013]作业(莫队+树状数组)
传送门 解题思路 莫队+树状数组.把求\([a,b]\)搞成前缀和形式,剩下的比较裸吧,用\(cnt\)记一下数字出现次数.时间复杂度\(O(msqrt(n)log(n)\),莫名其妙过了. 代码 # ...
随机推荐
- java ThreadGroup 作用 方法解析(转)
ThreadGroup线程组,java对这个类的描述呢就是“线程组表示一组线程.此外,线程组还可以包括其他线程组.线程组形成一个树,其中除了初始线程组之外的每个线程组都有一个父线程组.允许线程访问关于 ...
- 记日杂-log4net组件使用
下面我给大家介绍一下记日杂-log4net组件使用,当程序发布有服务器上,有时出现了错误, 都不知道出现在那,所以log4net组件很好解决这个问题. 1.添加开发包,并对log4net.dll的引用 ...
- Spring学习笔记(一)
Spring学习笔记(一) 这是一个沉淀的过程,大概第一次接触Spring是在去年的这个时候,当初在实训,初次接触Java web,直接学习SSM框架(当是Servlet都没有学),于是,养成了一个很 ...
- HTML+CSS常用代码(笔记)
注释标签:对代码进行说明 <!-- 单行注释,也可以对多行文字进行注释 --> 常用格式标签 <b>加粗</b> <i>斜体</i> < ...
- 永久修改Putty设置
在使用远程登录Putty时,会发现修改一些设置并且退出后发现自己之前改的设置不见了,可以通过保存设置解决 假设我要修改远程终端的背景颜色,选择系统颜色 勾选后,如果不保存下次登入时又要进行设置 点击D ...
- 使用Iview时候 报:no-parsing-error Parsing error: x-invalid-end-tag 解决办法
解决办法有两种解决办法: 1.MenuItem修改为:menu-item 2.在根目录下 .eslintrc.js 文件 rules 下添加: "vue/no-parsing-error&q ...
- Centos系统修改docker默认网络参数
刚Yum装完发现是没有网上所说的/etc/default/docker文件的,自己vim后其实也是不生效的. 因为Docker的systemd启动脚本(/usr/lib/systemd/system/ ...
- hdu 1215 求约数和 唯一分解定理的基本运用
http://acm.hdu.edu.cn/showproblem.php?pid=1215 题意:求解小于n的所有因子和 利用数论的唯一分解定理. 若n = p1^e1 * p2^e2 * ……*p ...
- mybatis数组和集合的长度判断及插入
1.在使用foreach的是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下4种情况: 如果传入的是单参数且参数类型是一个List的时候,collect ...
- Datetime 在C#中的用法 获取当前时间的各种格式
DateTime 获得当前系统时间: DateTime dt = DateTime.Now; Environment.TickCount可以得到“系统启动到现在”的毫秒值 DateTime now = ...