洛谷 P2709 BZOJ 3781 小B的询问
题目描述
小B有一个序列,包含N个1~K之间的整数。他一共有M个询问,每个询问给定一个区间[L..R],求$\sum_1^Kc_i^2$的值,其中$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
吐槽
BZOJ居然把这题设成权限题,我们这种穷人做不起啊,放个题号吧。
我的代码在洛谷上跑的挺快,刚开始没开O2,跑了1900+ms,然后去大牛分站交了一波,瞬间540毫秒,rank3了啊!估计我的程序最大的耗时处在两个sort上,algorithm里的东西和STL里的东西缺氧,吸了氧就跑得飞快,几乎是缺氧时的四倍速度了。
后来加快读、乘法换成位运算、另开一个数组$O(m)$记录答案而不是第二次排序,尤其是最后一项,整整少了60ms,终于卡到了473ms,目前的洛谷rank1.
解题思路
一道裸的莫队。莫队的原理可以看我这篇博文,每个莫队题目最重要的步骤都是推导出区间中减少一个元素或加入一个元素后答案的变化。
这题推公式不难。设当前区间$[l,r]$的答案为$t$,那么增加(l--或r++)一个元素时,设增加元素的颜色为k (l-1或r+1),$f(k)$为题目中的$c(k)$,那么$t+=(f(k)+1)^2-f^2(k)=2*f(k)+1$,同理,减少一个颜色为k的元素时$t-=f^2(k)-(f(k)-1)^2=2*f(k)-1$,于是就套上莫队的标志“四个while”吧。
源代码
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std; inline int get()
{
char c;short f = ; int res = ;
while (( (c=getchar())<||c>) && c!= '-');
if (c=='-') f = -;
else res = c- '';
while ( (c = getchar()) >= && c <= )
res = res * + c -'';
return f *res;
} int n,m,k;
int c[]={};
int f[]={}; struct query{
int id,pos,l,r,ans;
}a[];
int aa[]={};
inline int cmp1(const query & a,const query & b)
{
return a.pos==b.pos?a.r<b.r:a.pos<b.pos;
}
int main()
{
n=get(),m=get(),k=get();
for(int i=;i<=n;i++)
c[i]=get();
for(int i=,l,r,kuai=sqrt(n);i<=m;i++)
{
l=get();
r=get();
a[i]={i,l/kuai,l,r,};
}
sort(a+,a++m,cmp1);
for(int i=,l=,r=,t=;i<=m;i++)
{
while(r<a[i].r)
{
r+=;
t+=(f[c[r]]<<)+;
f[c[r]]+=;
}
while(l<a[i].l)
{
t-=(f[c[l]]<<)-;
f[c[l]]--;
l++;
}
while(l>a[i].l)
{
l--;
t+=(f[c[l]]<<)+;
f[c[l]]++;
}
while(r>a[i].r)
{
t-=(f[c[r]]<<)-;
f[c[r]]--;
r--;
}
a[i].ans=t;
}
for(int i=;i<=m;i++) aa[a[i].id]=a[i].ans-;
for(int i=;i<=m;i++) printf("%d\n",aa[i]);
return ;
}
洛谷 P2709 BZOJ 3781 小B的询问的更多相关文章
- 洛谷P2709 BZOJ 3781 小B的询问 (莫队)
题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重 ...
- BZOJ 3781: 小B的询问
3781: 小B的询问 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 643 Solved: 435[Submit][Status][Discuss ...
- bzoj 3781: 小B的询问 分块
3781: 小B的询问 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 196 Solved: 135[Submit][Status] Descrip ...
- Bzoj 3781: 小B的询问 莫队,分块,暴力
3781: 小B的询问 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 426 Solved: 284[Submit][Status][Discuss ...
- 【模板】BZOJ 3781: 小B的询问 莫队算法
http://www.lydsy.com/JudgeOnline/problem.php?id=3781 N个数的序列,每次询问区间中每种数字出现次数的平方和,可以离线. 丢模板: #include ...
- bzoj 3781 小B的询问——分块
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3781 非常经典的分块套路.于是时间空间比大家的莫队差了好多…… #include<io ...
- bzoj 3781 小B的询问 —— 莫队
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3781 就是莫队,左端点分块排序,块内按右端点排序,然后直接做即可. 代码如下: #inclu ...
- bzoj 3781 小B的询问(莫队算法)
[题意] 若干个询问sigma{ cnt[i]^2 } cnt[i]表示i在[l,r]内的出现次数. [思路] 莫队算法,裸题. 一个cnt数组即可维护插入与删除. [代码] #include< ...
- BZOJ 3781: 小B的询问 [莫队]
求区间每种颜色出现次数平方和 写裸题练手 #include <iostream> #include <cstdio> #include <algorithm> #i ...
随机推荐
- SetWindowPos函数详解
//声明:SetWindowPos(hWnd: HWND; {窗口句柄}hWndInsertAfter: HWND; {窗口的 Z 顺序}X, Y: Integer; {位置}cx, cy: Inte ...
- Android - Fragment BackStack 清空
Fragment BackStack 清空 int backStackCount = getFragmentManager().getBackStackEntryCount(); for(int i ...
- 洛谷 P3128 [ USACO15DEC ] 最大流Max Flow —— 树上差分
题目:https://www.luogu.org/problemnew/show/P3128 倍增求 lca 也写错了活该第一次惨WA. 代码如下: #include<iostream> ...
- rpmbuild
rpm2cpio xxx.rpm | cpio -div
- Constructing Roads In JGShining's Kingdom(LIS)
http://acm.hdu.edu.cn/showproblem.php?pid=1025 题意:富人路与穷人路都分别有从1到n的n个点,现在要在富人点与穷人点之间修路,但是要求路不能交叉,问最多能 ...
- hdu2089不要62(数位dp)
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 洛谷P1077 摆花(背包dp)
P1077 摆花 题目描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆.通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号.为了在门口展出更多种花,规定第i种花不能 ...
- Appium + python - input操作实例
import osimport time as t adb = 'adb shell input tap 400 500'os.system(adb) t.sleep(5) class keyeven ...
- Dijkstra TYVJ 1031热浪 Dijkstra测试数据
测试用邻接表写得Dijkstra 代码写得很烂. 描述 德克萨斯纯朴的民眾们这个夏天正在遭受巨大的热浪!!!他们的德克萨斯长角牛吃起来不错,可是他们并不是很擅长生產富含奶油的乳製品.Farmer Jo ...
- JavaScript 关于DOM的事件操作
一.JavaScript的组成 JavaScript基础分为三个部分: ECMAscript:JavaScript的标准语法.包括变量,表达式,运算符,函数,if语句,for语句等. DOM:文档对象 ...