「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\)个祖先匹配啊 于是可以暴力枚举祖先链 ...
随机推荐
- uva 10566 Crossed Ladders (二分)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...
- idea乱码问题(全)
中文乱码问题分类: 编码普通中文乱码 properties文件中文乱码 console控制台中文乱码 搜索框中文乱码 svn注释中文乱码 问题截图: 2.properties文件中文乱码 4,.搜索框 ...
- cmd导入比较大的sql脚本
osql -S jack_c -d yourdb -U sa -P 123 -i E:\user.sql 注意: sql脚本里面一定要先创建数据库或者use到某个数据库,然后再cmd执行脚本
- asp.net mvc获取路由参数
学习了mvc有一段时间了,本以为直接可以通过request对象直接获取路由参数呢,后来实验了一下发现想错了,mvc有专门获取路由参数的方式,在不同的地方,获取路由参数的方式也不一样,这里分别说一下,在 ...
- jq杂项方法/工具方法----isArray()
https://www.cnblogs.com/sandraryan/ $.isArray()函数用于判断指定参数是否是一个数组.返回布尔值. <!DOCTYPE html> <ht ...
- 2019-6-23-win10-uwp-解决-SerialDevice.FromIdAsync-返回空
title author date CreateTime categories win10 uwp 解决 SerialDevice.FromIdAsync 返回空 lindexi 2019-6-23 ...
- Flex AIR应用的启动闪屏(必须)
说明: 一款移动应用,它必须具有启动屏幕,这点可以从我们常见的手机应用观察知道(如,你启动一个QQ,开始大约10秒钟会停留在一个界面上,之后才跳转到登陆或者是主界面). 在air移动应用中,如果不添加 ...
- HDU 1372
题意:模拟国际象棋马的走棋方式,和中国象棋一样马走日,8X8的棋盘,问从起点到终点的最短步数,国际象棋中数字代表行row,字母代表列column, 思路:记忆化深搜. #include<cstd ...
- Yarn install 报错 Resolving packages... [2/4] Fetching packages... info There appears to be trouble with your network connection. Retrying
1.设置淘宝代理 yarn config set registry 'https://registry.npm.taobao.org' 2.如果网址本地可以打开,说明你本地有代理设置 所以需要按本地的 ...
- jackson java转json hibernate懒加载造成的无限递归问题
@JsonIgnore @JsonFilter @JsonBackReference @JsonManagedReference @JsonIgnoreProperties jackson中的@Jso ...