bzoj3781小B的询问*

bzoj3781小B的询问

题意:

给定一个长度为n的序列,序列里的数≤k,m个询问l,r:求sigma(i,1,k)c[i]^2,c[i]为i在[l,r]的出现次数。n,m,k≤50000。

题解:

莫队算法直接上。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cmath>
 5 #define inc(i,j,k) for(int i=j;i<=k;i++)
 6 #define maxn 50010
 7 #define ll long long
 8 using namespace std;
 9
10 inline int read(){
11     char ch=getchar(); int f=1,x=0;
12     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();}
13     while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar();
14     return f*x;
15 }
16 struct ask{int l,r,id;}asks[maxn]; int bel[maxn],n,sz,m,k,l,r; ll ans,a[maxn],c[maxn],p[maxn];
17 bool cmp(ask a,ask b){return bel[a.l]==bel[b.l]?a.r<b.r:bel[a.l]<bel[b.l];}
18 ll sqr(ll a){return a*a;}
19 int main(){
20     n=read(); m=read(); k=read(); inc(i,1,n)a[i]=read(); sz=(int)sqrt(n);
21     inc(i,1,n)bel[i]=(i-1)/sz+1; inc(i,1,m)asks[i]=(ask){read(),read(),i};
22     sort(asks+1,asks+m+1,cmp); ans=0; l=1; r=0;
23     inc(i,1,m){
24         while(asks[i].r>r)r++,ans-=sqr(c[a[r]]),c[a[r]]++,ans+=sqr(c[a[r]]);
25         while(asks[i].l<l)l--,ans-=sqr(c[a[l]]),c[a[l]]++,ans+=sqr(c[a[l]]);
26         while(asks[i].r<r)ans-=sqr(c[a[r]]),c[a[r]]--,ans+=sqr(c[a[r]]),r--;
27         while(asks[i].l>l)ans-=sqr(c[a[l]]),c[a[l]]--,ans+=sqr(c[a[l]]),l++;
28         p[asks[i].id]=ans;
29     }
30     inc(i,1,m)printf("%lld\n",p[i]); return 0;
31 }

20160906

时间: 2024-12-29 23:12:58

bzoj3781小B的询问*的相关文章

bzoj3781 小B的询问

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3781 [题解] 将x^2差分成1+3+5+...+(x+x-1)即可莫队了.顺手3min码出来了(兹磁啊) 复杂度$O(n\sqrt{n})$ # include <math.h> # include <stdio.h> # include <string.h> # include <iostream> # include <algorithm&

【莫队算法】bzoj3781 小B的询问

莫队经典. 开个数组维护a[i]出现的次数. 1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 int Num,CH[12],f,c; 6 inline void R(int &x){ 7 c=0;f=1; 8 for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1; 9 for(x=0;c>=

Bzoj 3781: 小B的询问 莫队,分块,暴力

3781: 小B的询问 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 426  Solved: 284[Submit][Status][Discuss] Description 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数.小B请你帮助他回答询问. Input 第一行,三个整数N.M.K. 第二行

[BZOJ3781][P2709]小B的询问[莫队]

入门题 对于一个区间的询问,如果在已知\([l,r]\)的答案时可以用O(1)的时间求出左右端点\(±1\)的答案,就可以使用莫队来优化. 设已知区间为\([l_1,r_1]\),所求区间为\([l_2,r_2]\) 可知求得\([l_2,r_2]\)的成本是\(|l_1-l_2| + |r_1-r_2|\)如果把这两个区间看成点,这个成本就是两点的曼哈顿距离, 对于多个询问,求出曼哈顿距离最小生成树就可以以最小成本获得答案,使用一种奇怪的方式 --sort来获得最优的转移方式 我并不知道原理

洛谷 P2709 BZOJ 3781 小B的询问

题目描述 小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个询问的答案. 输入输出样例 输入样例#1: 6 4 3 1 3 2 1 1 3

luogu P2709 小B的询问

题目描述 小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个询问的答案. 输入输出样例 输入样例#1: 6 4 3 1 3 2 1 1 3

洛谷 P2709 小B的询问

https://www.luogu.org/problem/show?pid=2709 题目描述 小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行的整数表

P2709 小B的询问

题目描述 小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个询问的答案. 输入输出样例 输入样例#1: 6 4 3 1 3 2 1 1 3

luoguP2709 小B的询问 [莫队]

题目描述 小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个询问的答案. 输入输出样例 输入样例#1: 6 4 3 1 3 2 1 1 3