博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj 4241 历史研究——分块(区间加权众数)
阅读量:6877 次
发布时间:2019-06-26

本文共 1396 字,大约阅读时间需要 4 分钟。

题目:

套路:可以大力预处理,如果求区间加权众数,可以预处理i~j块(或 j 位置)的最大值,为了暴力再预处理i~j块每个数出现次数;这个i~j可以记录成从第i块开始的后缀,这样空间还是n*w。

如果不无脑开long long可以快18s。

#include
#include
#include
#include
#include
#define ll long longusing namespace std;const int N=1e5+5;int n,q,base,bh[N],sta[N],top,a[N],c[N],cnt[320][N],nm[N];ll f[320][N];int main(){ scanf("%d%d",&n,&q);base=sqrt(n); for(int i=1;i<=n;i++) { scanf("%lld",&a[i]);c[i]=a[i]; bh[i]=(i-1)/base+1; } sort(c+1,c+n+1);int tot=unique(c+1,c+n+1)-c-1; for(int i=1;i<=n;i++)a[i]=lower_bound(c+1,c+tot+1,a[i])-c; for(int i=1;i<=bh[n];i++) { ll tmp=0; for(int j=(i-1)*base+1;j<=n;j++)//i,not bh[i] cnt[i][a[j]]++,tmp=max(tmp,(ll)cnt[i][a[j]]*c[a[j]]),f[i][j]=tmp;//这里把j表示成具体位置也行(好?) //c[a[j]] //之所以用tmp,是为了把之前的值曾达到的最大值也算在自己里 } int x,y; while(q--) { scanf("%d%d",&x,&y); ll ans=f[bh[x]+1][y]; for(int i=(bh[y]-1)*base+1;i<=y;i++) nm[a[i]]++,sta[++top]=a[i]; for(int i=x;i<=bh[x]*base&&i<=n;i++) nm[a[i]]++,sta[++top]=a[i],ans=max(ans,(ll)(cnt[bh[x]+1][a[i]]-cnt[bh[y]][a[i]]+nm[a[i]])*c[a[i]]); printf("%lld\n",ans); for(int i=1;i<=top;i++)nm[sta[i]]=0;top=0; } return 0;}

 

转载于:https://www.cnblogs.com/Narh/p/9298670.html

你可能感兴趣的文章
sync.Map源码分析
查看>>
error: invalid storage class for function
查看>>
seci-log 1.08 发布 增加snmp trap v2c和v3的收集
查看>>
jquery通过url传递 和 接收 参数
查看>>
禁用火狐14以后plugin进程
查看>>
linux增加swap分区
查看>>
Android软键盘的显示与隐藏
查看>>
ThreadPool 线程池
查看>>
AWK 文件处理计数
查看>>
我的友情链接
查看>>
AI技术说:人工智能相关概念与发展简史
查看>>
eclipse启动失败
查看>>
(已解决!)精选30道Java笔试题解答
查看>>
【Python之旅】第七篇(三):使用Redis订阅服务
查看>>
linux远程桌面链接windows
查看>>
TrendMicro:新的APT***针对亚洲和欧洲政府组织,包括中国媒体机构
查看>>
C语言中sizeof与strlen区别2
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
我的友情链接
查看>>