bzoj4241 历史研究——分块
2024-08-28 12:05:12
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4241
就是分块,预处理出从第 i 块到 j 位置的答案,以及从第 i 块到最后位置间每个数出现的次数;
然后块内统计、块外暴力即可。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=1e5+;
int n,q,a[maxn],b[maxn],cnt[][maxn],sta[maxn],top,m,tot,blk[maxn],num[maxn];
ll f[][maxn];
int main()
{
scanf("%d%d",&n,&q); tot=sqrt(n);
for(int i=;i<=n;i++)blk[i]=(i-)/tot+;
for(int i=;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];
sort(b+,b+n+); m=unique(b+,b+n+)-b-;
for(int i=;i<=n;i++)a[i]=lower_bound(b+,b+m+,a[i])-b;
for(int i=;i<=blk[n];i++)
{
ll nw=;
for(int j=lower_bound(blk+,blk+n+,i)-blk;j<=n;j++)
cnt[i][a[j]]++,nw=max(nw,(ll)cnt[i][a[j]]*b[a[j]]),f[i][j]=nw;//cnt是第i块a[j]数量后缀
//f[i][j]表示第i块到j位置的答案
}
for(int i=,x,y;i<=q;i++)
{
scanf("%d%d",&x,&y);
ll ans=f[blk[x]+][y];
int st=lower_bound(blk+,blk+n+,blk[y])-blk;
for(int i=st;i<=y;i++)num[a[i]]++,sta[++top]=a[i];
st=lower_bound(blk+,blk+n+,blk[x]+)-blk;
for(int i=x;i<st;i++)
{
num[a[i]]++;
ans=max(ans,(ll)(cnt[blk[x]+][a[i]]-cnt[blk[y]][a[i]]+num[a[i]])*b[a[i]]);
sta[++top]=a[i];
}
printf("%lld\n",ans);
while(top)num[sta[top]]=,top--;//不用memset
}
return ;
}
最新文章
- AngularJS表达式
- JavaScript局部变量和全局变量的理解
- xp 安装 win7 64
- [UIView beginAnimations:context:]与[UIView animateWithDuration:animations:]值得注意的一个区别
- wince和window mobile winphone
- leetcode之Count Complete Tree Nodes
- centos 单独安装nginx
- window配置临时环境变量
- Topcoder口胡记 SRM 562 Div 1 ~ SRM 599 Div 1
- vue 双向数据绑定原理
- HashMap 与 ConcrrentHashMap 使用以及源码原理分析
- dump、load和dumps、loads的区别
- 四则运算 来源:一位热心的网友 http://www.tqcto.com/article/software/336297.html
- CentOS6.8启动Tomcat无法访问
- 反爬虫之JS反编译:PyExecJS
- hadoop基础学习---数据管理策略
- 【网络】RFC1245-OSPF Protocol Analysis
- Android IPC
- LArea 微信端 地址选择
- 【转】java:多网卡环境下获取MAC地址