【説明する】莫队
-
- 693通过
- 1.5K提交
- 题目提供者 lych
- 标签 各省省选 2009山东 云端
- 难度 提高+/省选-
- 时空限制 1s / 128MB
题目背景
无
题目描述
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。
思路:
1)莫队
2)离线+树状数组(然而我并不会(๑¯∀¯๑))
上代码╰( ̄▽ ̄)╮:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define LL long long
using namespace std;
const int N = 50010;
const int M = 200010;
int n,m,k,curL,curR;
int answer;
int a[N];
LL cnt[M],ans[M];
struct G {
int l,r,id,block;
bool operator < (const G &qwq)const
{
if(block==qwq.block)
return r < qwq.r;
else
return block < qwq.block;
}
}t[M];
void add(int pre)
{
if(++cnt[a[pre]] == 1)
answer++;
}
void change(int pre)
{
if(--cnt[a[pre]] == 0)
answer--;
}
void modui()
{
sort(t+1,t+m+1);
curL=1,curR=0;
for(int i=1;i<=m;i++)
{
int L=t[i].l,R=t[i].r;
while(curL<L)
change(curL++);
while(curL>L)
add(--curL);
while(curR<R)
add(++curR);
while(curR>R)
change(curR--);
ans[t[i].id]=answer;
}
}
int main()
{
scanf("%d",&n);
int size=sqrt(n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
for(int i=1,l,r;i<=m;i++)
{
scanf("%d%d",&t[i].l,&t[i].r);
t[i].id=i;
t[i].block=(t[i].l-1)/size+1;
}
modui();
for(int i=1;i<=m;i++)
printf("%d\n",ans[i]);
return 0;
}
-
- 157通过
- 244提交
- 题目提供者 BDF1
- 标签 云端↑
- 难度 提高+/省选-
- 时空限制 1s / 128MB
题目描述
小B有一个序列,包含N个1~K之间的整数。他一共有M个询问,每个询问给定一个区间[L..R],求(Sigma)∑(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数。
小B请你帮助他回答询问。
输入输出格式
输入格式:第一行,三个整数N、M、K。
第二行,N个整数,表示小B的序列。
接下来的M行,每行两个整数L、R。
输出格式:M行,每行一个整数,其中第i行的整数表示第i个询问的答案。
输入输出样例
6 4 3
1 3 2 1 1 3
1 4
2 6
3 5
5 6
6
9
5
2
说明
对于全部的数据,1<=N、M、K<=50000
思路(*^__^*) :
裸的莫队题...只是可惜我是真的没搞明白为什么可以这样做...然后胡乱敲了一个模板,啪的一下就AC了....
坑点qaq:
看样子好像并没有使用到k...
代码酱=u=:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define LL long long
using namespace std;
const int N = 50010;
int n,m,k,curL,curR;
int answer;
int a[N];
LL cnt[N],ans[N];
struct G {
int l,r,num,block;
bool operator < (const G &qwq)const
{
if(block==qwq.block)
return r < qwq.r;
else
return block < qwq.block;
}
}t[N];
void change(int pre,bool flag)
{
if(flag)
answer-=(--cnt[a[pre]])<<1|1;
else
answer+=(cnt[a[pre]]++)<<1|1;
}
void modui()
{
sort(t+1,t+m+1);
curL=1,curR=0;
for(int i=1;i<=m;i++)
{
int L=t[i].l,R=t[i].r;
while(curL<L)
change(curL++,1);
while(curL>L)
change(--curL,0);
while(curR<R)
change(++curR,0);
while(curR>R)
change(curR--,1);
ans[t[i].num]=answer;
}
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
int size=sqrt(n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1,l,r;i<=m;i++)
{
scanf("%d%d",&t[i].l,&t[i].r);
t[i].num=i;
t[i].block=(t[i].l-1)/size+1;
}
modui();
for(int i=1;i<=m;i++)
printf("%lld\n",ans[i]);
return 0;
}
(___r___)
参考博客:
1.http://foreseeable97.logdown.com/posts/158522-233333
2.http://www.cnblogs.com/hzf-sbit/p/4056874.html
3.http://ydcydcy1.blog.163.com/blog/static/21608904020134411543898/
4.http://vawait.com/manhattanmst/
5.http://blog.csdn.net/huzecong/article/details/8576908