题面

给出一个\(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 解题报告的更多相关文章

  1. 「FJOI2016」神秘数 解题报告

    「FJOI2016」神秘数 这题不sb,我挺sb的... 我连不带区间的都不会哇 考虑给你一个整数集,如何求这个神秘数 这有点像一个01背包,复杂度和值域有关.但是你发现01背包可以求出更多的东西,就 ...

  2. 「ZJOI2016」大森林 解题报告

    「ZJOI2016」大森林 神仙题... 很显然线段树搞不了 考虑离线操作 我们只搞一颗树,从位置1一直往后移动,然后维护它的形态试试 显然操作0,1都可以拆成差分的形式,就是加入和删除 因为保证了操 ...

  3. 「SCOI2016」背单词 解题报告

    「SCOI2016」背单词 出题人sb 题意有毒 大概是告诉你,你给一堆n个单词安排顺序 如果当前位置为x 当前单词的后缀没在这堆单词出现过,代价x 这里的后缀是原意,但不算自己,举个例子比如abc的 ...

  4. 「NOI2015」寿司晚宴 解题报告

    「NOI2015」寿司晚宴 这个题思路其实挺自然的,但是我太傻了...最开始想着钦定一些,结果发现假了.. 首先一个比较套路的事情是状压前8个质数,后面的只会在一个数出现一次的再想办法就好. 然后发现 ...

  5. 「SCOI2015」国旗计划 解题报告

    「SCOI2015」国旗计划 蛮有趣的一个题 注意到区间互不交错,那么如果我们已经钦定了一个区间,它选择的下一个区间是唯一的,就是和它有交且右端点在最右边的,这个可以单调队列预处理一下 然后往后面跳拿 ...

  6. 「JLOI2015」骗我呢 解题报告?

    「JLOI2015」骗我呢 这什么神仙题 \[\color{purple}{Link}\] 可以学到的东西 对越过直线的东西翻折进行容斥 之类的..吧? Code: #include <cstd ...

  7. 「JLOI2015」城池攻占 解题报告

    「JLOI2015」城池攻占 注意到任意两个人的战斗力相对大小的不变的 可以离线的把所有人赛到初始点的堆里 然后做启发式合并就可以了 Code: #include <cstdio> #in ...

  8. 「JLOI2015」管道连接 解题报告

    「JLOI2015」管道连接 先按照斯坦纳树求一个 然后合并成斯坦纳森林 直接枚举树的集合再dp一下就好了 Code: #include <cstdio> #include <cct ...

  9. 「JLOI2015」战争调度 解题报告

    「JLOI2015」战争调度 感觉一到晚上大脑就宕机了... 题目本身不难,就算没接触过想想也是可以想到的 这个满二叉树的深度很浅啊,每个点只会和它的\(n-1\)个祖先匹配啊 于是可以暴力枚举祖先链 ...

随机推荐

  1. Python基础:27执行环境

    一:可调用对象 可调用对象,是任何能通过函数操作符“()”来调用的对象.Python 有4 种可调用对象:函数,方法,类,以及一些类的实例. 1:函数 python 有 3 种不同类型的函数对象. a ...

  2. 2015年热门的国产开源软件TOP 50

    2015年热门的国产开源软件TOP 50 开源中国在 2015 年得到了快速的发展,单开源软件收藏量就接近 40000 款,其中不乏优质的国产开源项目.本文从软件的收藏.下载.访问等多角度挑选出了 2 ...

  3. C# POST 表单发送文件

    表单提交协议规定:要先将 HTTP 要求的 Content-Type 设为 multipart/form-data,而且要设定一个 boundary 参数,这个参数是由应用程序自行产生,它会用来识别每 ...

  4. 本地测试读取redis和普通文件缓存的速度,redis慢一倍?

    重新测试了,换成了Linux服务器,php5.6,512内存.连续读取1千次不同的文件(每个文件41KB),redis也是1千个不同的key,文件缓存还是比redis快! 但是,但是,后来我换成连续读 ...

  5. PHP中 spl_autoload_register() 函数用法

    这篇文章主要介绍了PHP中spl_autoload_register()函数用法,结合实例形式分析了__autoload函数及spl_autoload_register函数的相关使用技巧,需要的朋友可 ...

  6. oracle sum()聚合函数

    原文链接:https://blog.csdn.net/cizatu5130/article/details/100291347 oracle sum()聚合函数 2016-05-13 20:08:00 ...

  7. Java反射机制(二):通过反射取得类的结构

    在反射运用过程中,如果你想得到一个类的完整结构,那么就要使用到java.lang.reflect包中的几个类: · Constructor  表示类中的构造方法 · Field  表示类中的属性 · ...

  8. Python--day28--面试题

  9. HDU 1286

    欧拉函数 φ函数的值 通式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数.φ(1)=1 ...

  10. linux模块参数

    驱动需要知道的几个参数因不同的系统而不同. 从使用的设备号( 如我们在下一章见到的 ) 到驱动应当任何操作的几个方面. 例如, SCSI 适配器的驱动常常有选项控制标记命令队列 的使用, IDE 驱动 ...