「CF86D」Powerful array 解题报告
题面
给出一个\(n\)个数组成的数列\(a\),有\(t\)次询问,每次询问为一个\([l,r]\)的区间,求区间内每种数字出现次数的平方×数字的值 的和
思路:
直接上莫队咯 然后就T了
没学过莫队?!我也没办法
这道题的数据范围在\(2e5\)的级别,有人会问莫队肯定要炸啊 捏~
时限5000ms,那就可以乱搞了
但是!还是要加一些优化
如何优化?
1.对于算法本身的优化
由于莫队可以说是一个块状暴力的算法,就是把区间划分为\(\sqrt n\)块然后在块内暴力(到头还是暴力)
我们可以把要查询的区间当做点表示在平面直角坐标系上,RT:

就像这样把询问放在平面直角坐标系上,\(\large x\)轴为询问该区间的顺序,\(\large y\)轴表示该区间的右端点,如果我们忽略区间的\(L\)值的影响,不难看出,虽然我们已经把区间划分在一个块里了,但是还是有很多冗余的操作,如果要是这些冗余的操作少一点就好了,这当然可以啦!
我们可以让块内的区间按\(\large R\) 递增,这样能省很多时间,但是在区间过渡的时候,我们还是会做很多多余的操作,因为区间都是递增的,这样改变块的时候就可能有一个很大的落差,就掉了下去,可以自己想象一下

为了避免上述的现象,我们可以让区间像一个波浪一样,这样就很高效了,这样的划分方式叫做奇偶划分应该是这么叫的吧,还有一个是奇偶性剪枝
inline bool cmp(node a,node b){//代码是关键,讲了啥不重要(手动划线)
return (pos[a.l]==pos[b.l])?(pos[a.l]&1)?a.r<b.r:a.r>b.r : a.l<b.l;
}//千万不要写if,会T!
接着就是块的大小,同样影响速度,一般普通的块的大小应该是\(\large \sqrt n\),但是,根据某奆佬研究,大小为\(\large n^{0.54}\)时更快,Orz
2.对于程序本身优化,说人话就是卡卡常
比如:
加点
register非递归函数前加个
inline不用快读用
fread还有!乘法变加法……
然后就把最大时间卡到了622ms
啊哈哈哈哈哈
Code:
#include<bits/stdc++.h>
#define getchar() *(p++)//在快读基础上改一点就行了
#define Re register//卡常必备
#define ll long long
#define M 1000010
#define N 200010
using namespace std;
struct node{
int l,r,i;
}b[N];//sum是数的多少,pos表示在哪块
int a[N],pos[N],n,m,sum[M],l,r,block;
ll Ans[N],ans;
char bf[1<<25],*p;
int read(){
Re int s=0;
Re char c=getchar();
while(!isdigit(c))
c=getchar();
while(isdigit(c))
{
s=(s<<1)+(s<<3)+c-'0';
c=getchar();
}
return s;
}
inline bool cmp(node a,node b){//奇偶划分
return (pos[a.l]==pos[b.l])?(pos[a.l]&1)?a.r<b.r:a.r>b.r : a.l<b.l;
}//注意,这里不要写if语句,会T
inline void Add(Re ll x)
{
sum[x]++;//有些人写在前面,那样的话就应该是+1
ans+=(sum[x]+sum[x]-1)*x;//就是由原来的乘变成了加,手算一小部分也没有关系啦
}
inline void Del(Re ll x)
{
ans-=(sum[x]+sum[x]-1)*x;//这里和上面也是一样的
sum[x]--;//为什么我感觉上面-1会更慢呢~
}
int main()
{
Re int i;
bf[fread(bf,1,1<<25,stdin)]='\0';p=bf;//fread大法
n=read();m=read();block=pow(n,0.54);//神奇的块的大小
for(i=1;i<=n;i++)
a[i]=read(),pos[i]=i/block;
for(i=1;i<=m;i++)
b[i].l=read(),b[i].r=read(),b[i].i=i;
sort(b+1,b+1+m,cmp);l=1;
for(i=1;i<=m;i++)//然后上莫队
{
while(r<b[i].r)
Add(a[++r]);
while(r>b[i].r)
Del(a[r--]);
while(l<b[i].l)
Del(a[l++]);
while(l>b[i].l)
Add(a[--l]);
Ans[b[i].i]=ans;
}
for(i=1;i<=m;i++)
printf("%lld\n",Ans[i]);
return 0;
}
再说一遍
最后注意,sort的时候,如果数组本来就有序了,sort会很慢,所以千万不要在里面加if了,容易T
「CF86D」Powerful array 解题报告的更多相关文章
- 「FJOI2016」神秘数 解题报告
「FJOI2016」神秘数 这题不sb,我挺sb的... 我连不带区间的都不会哇 考虑给你一个整数集,如何求这个神秘数 这有点像一个01背包,复杂度和值域有关.但是你发现01背包可以求出更多的东西,就 ...
- 「ZJOI2016」大森林 解题报告
「ZJOI2016」大森林 神仙题... 很显然线段树搞不了 考虑离线操作 我们只搞一颗树,从位置1一直往后移动,然后维护它的形态试试 显然操作0,1都可以拆成差分的形式,就是加入和删除 因为保证了操 ...
- 「SCOI2016」背单词 解题报告
「SCOI2016」背单词 出题人sb 题意有毒 大概是告诉你,你给一堆n个单词安排顺序 如果当前位置为x 当前单词的后缀没在这堆单词出现过,代价x 这里的后缀是原意,但不算自己,举个例子比如abc的 ...
- 「NOI2015」寿司晚宴 解题报告
「NOI2015」寿司晚宴 这个题思路其实挺自然的,但是我太傻了...最开始想着钦定一些,结果发现假了.. 首先一个比较套路的事情是状压前8个质数,后面的只会在一个数出现一次的再想办法就好. 然后发现 ...
- 「SCOI2015」国旗计划 解题报告
「SCOI2015」国旗计划 蛮有趣的一个题 注意到区间互不交错,那么如果我们已经钦定了一个区间,它选择的下一个区间是唯一的,就是和它有交且右端点在最右边的,这个可以单调队列预处理一下 然后往后面跳拿 ...
- 「JLOI2015」骗我呢 解题报告?
「JLOI2015」骗我呢 这什么神仙题 \[\color{purple}{Link}\] 可以学到的东西 对越过直线的东西翻折进行容斥 之类的..吧? Code: #include <cstd ...
- 「JLOI2015」城池攻占 解题报告
「JLOI2015」城池攻占 注意到任意两个人的战斗力相对大小的不变的 可以离线的把所有人赛到初始点的堆里 然后做启发式合并就可以了 Code: #include <cstdio> #in ...
- 「JLOI2015」管道连接 解题报告
「JLOI2015」管道连接 先按照斯坦纳树求一个 然后合并成斯坦纳森林 直接枚举树的集合再dp一下就好了 Code: #include <cstdio> #include <cct ...
- 「JLOI2015」战争调度 解题报告
「JLOI2015」战争调度 感觉一到晚上大脑就宕机了... 题目本身不难,就算没接触过想想也是可以想到的 这个满二叉树的深度很浅啊,每个点只会和它的\(n-1\)个祖先匹配啊 于是可以暴力枚举祖先链 ...
随机推荐
- 字符串编辑距离(Edit Distance)
一.问题描述定义字符串编辑距离(Edit Distance),是俄罗斯科学家 Vladimir Levenshtein 在 1965 年提出的概念,又称 Levenshtein 距离,是指两个字符串之 ...
- php三目运算计算三个数最大值最小值
文章地址:https://www.cnblogs.com/sandraryan/ $x = 10; $y = 45; $z = 3; //求出三个数字中最大值最小值 //先比较x y,如果x> ...
- Python--day47--mysql索引注意事项
- joinColumns和inverseJoinColumns的用法
最近在工作中使用springside,里面用到了hibernate的多对多 一开始我在配置department(部门表)和menu(栏目表)的时候,这样写的. Department实体类中的getMe ...
- Scrap简介
原文:https://blog.csdn.net/ssw_1990/article/details/51254227 提到Python与网络爬虫,可能会想到urllib,urllib2,Beautif ...
- 2018-8-10-dot-net-core-使用-IPC-进程通信
title author date CreateTime categories dot net core 使用 IPC 进程通信 lindexi 2018-08-10 19:16:52 +0800 2 ...
- 如何通过命令行 msbuild 编译项目
本文告诉大家如何通过 msbuild 编译一个项目,通过命令行编译可以输出更多的编译信息,可以用来调试自己写的编译相关方法,可以看到是哪个文件编译失败 在开始菜单可以找到 VisualStudio 的 ...
- JAXB常用注解讲解(超详细)
简介: JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术.该过程中,JAXB也提供了将XML实例 ...
- 51nod 范德蒙矩阵
思路: 根据矩阵乘法的定义,G中的第i行第j列的元素 ai,j ,对答案的贡献为 ai,j∗ T中第j行的所有元素之和. 因此我们可以将T中根据每行的和进行排序.第i行的和可以通过公式 (ai^n−1 ...
- js 中日期2013-08-30或2019-08-24 12:30:00 转换成时间戳,和2019-08-29T02:15:08.000+0000转化为2019-08-29T02:15:08
js 中日期2019-08-24 或2019-08-24 12:30:00 转换成时间戳 首先将它转成date日期类型,然后获取毫秒形式时间戳 let date=new Date("2019 ...