联赛模拟测试17 A. 简单的区间 启发式合并
题目描述

分析
我们要找的是一段区间的和减去该区间的最大值能否被 \(k\) 整除
那么对于一段区间,我们可以先找出区间中的最大值
然后枚举最大值左边的后缀与最大值右边的前缀之和是否能被 \(k\) 整除
显然暴力枚举肯定会超时
所以我们可以用启发式合并的思想,只枚举长度较小的那一半,而在某种数据结构中查询另一半对应的值
查询的过程可以用主席树,但是常数巨大
其实我们可以对于每一个 \(\%k\) 后的前缀和开一个 \(vector\)
\(vector\) 中存放该值出现的位置
然后大力二分即可,复杂度和主席树相同
注意具体查的值要推一下式子
代码
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#define rg register
inline int read(){
rg int x=0,fh=1;
rg char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') fh=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*fh;
}
const int maxn=3e5+5,maxm=1e6+5;
int n,k,a[maxn],sum[maxn],wz[maxn][22],ans,cnt[maxm],lg[maxn],b[maxn];
std::vector<int> g[maxm];
int cx(int l,int r){
rg int k=lg[r-l+1];
if(b[wz[l][k]]<b[wz[r-(1<<k)+1][k]]) return wz[r-(1<<k)+1][k];
else return wz[l][k];
}
int js(int id,int l,int r){
if(l>r || g[id].size()==0 || g[id][g[id].size()-1]<l) return 0;
return std::upper_bound(g[id].begin(),g[id].end(),r)-std::lower_bound(g[id].begin(),g[id].end(),l);
}
void solve(int l,int mids,int r){
if(l>mids || r<mids) return;
solve(l,cx(l,mids-1),mids-1);
solve(mids+1,cx(mids+1,r),r);
if(mids-l<r-mids){
for(rg int i=l;i<=mids;i++){
rg int now=(sum[i-1]+a[mids])%k;
ans+=js(now,mids+1,r);
}
ans+=js(sum[mids-1],l-1,mids-2);
} else {
for(rg int i=mids;i<=r;i++){
rg int now=(sum[i]-a[mids]+k)%k;
ans+=js(now,l-1,mids-2);
}
ans+=js(sum[mids],mids+1,r);
}
}
int main(){
n=read(),k=read();
for(rg int i=1;i<=n;i++){
a[i]=read();
b[i]=a[i];
a[i]%=k;
wz[i][0]=i;
}
for(rg int i=1;i<=n;i++){
sum[i]=sum[i-1]+a[i];
if(sum[i]>=k) sum[i]-=k;
g[sum[i]].push_back(i);
}
for(rg int i=2;i<=n;i++){
lg[i]=lg[i/2]+1;
}
for(rg int j=1;j<=20;j++){
for(rg int i=1;i+(1<<j)-1<=n;i++){
if(b[wz[i][j-1]]>b[wz[i+(1<<(j-1))][j-1]]){
wz[i][j]=wz[i][j-1];
} else {
wz[i][j]=wz[i+(1<<(j-1))][j-1];
}
}
}
g[0].push_back(0);
for(rg int i=0;i<k;i++){
std::sort(g[i].begin(),g[i].end());
}
rg int be=cx(1,n);
solve(1,be,n);
printf("%d\n",ans);
return 0;
}
联赛模拟测试17 A. 简单的区间 启发式合并的更多相关文章
- [CSP-S模拟测试]:模板(ac)(线段树启发式合并)
题目描述 辣鸡$ljh\ NOI$之后就退役了,然后就滚去学文化课了.他每天都被$katarina$大神虐,仗着自己学过一些姿势就给$katarina$大神出了一道题.有一棵$n$个节点的以$1$号节 ...
- [CSP-S模拟测试]:english(可持久化Trie+启发式合并)
题目传送门(内部题24) 输入格式 第一行有$3$个整数$n,opt$,$opt$的意义将在输出格式中提到.第二行有$n$个整数,第$i$个整数表示$a_i$. 输出格式 若$opt=1$,输出一行一 ...
- 联赛模拟测试22 D. 简单计算
题目描述 分析 \(\sum_{i=0}^p[(p|qi)?0:1]=\sum_{i=0}^p[(p/gcd(p,q)|qi/gcd(p,q))?0:1]=\sum_{i=0}^p[(p/gcd(p, ...
- NOIP模拟测试17&18
NOIP模拟测试17&18 17-T1 给定一个序列,选取其中一个闭区间,使得其中每个元素可以在重新排列后成为一个等比数列的子序列,问区间最长是? 特判比值为1的情况,预处理比值2~1000的 ...
- 模拟测试—moq:简单一两句
在Xunit的基础上,说话模拟测试. 假如我们有这样一个控制器里面有这样一个方法,如图 我们在对Bar测试得时候,如果测试未通过,错误有可能来至于Bar,也有可能错误来至于serverde Foo方法 ...
- 联赛模拟测试10 C. 射手座之日
题目描述 分析 方法一(线段树) 线段树维护的是以当前节点为左端点的区间的贡献 而区间的右端点则会从 \(1\) 到 \(n\) 逐渐右移 当我们把右端点从 \(i-1\) 的位置扩展到 \(i\) ...
- [考试反思]0811NOIP模拟测试17:虚无
(sdfz未参加,也就是一共就51个人) 也不粘具体排名了,只写分数线. []220 []201 []194 [5]181 [10]141 [15]132 [20]122 [25]116 [30]10 ...
- NOIP模拟测试17
T1:入阵曲 题目大意:给定一个N*M的矩形,问一共有多少个子矩形,使得矩形内所有书的和为k的倍数. 60%:N,M<=80 枚举矩形的左上角和右下角,用二维前缀和求出数字之和. 时间复杂度$O ...
- NOIP模拟测试17「入阵曲·将军令·星空」
入阵曲 题解 应用了一种美妙移项思想, 我们先考虑在一维上的做法 维护前缀和$(sum[r]-sum[l-1])\%k==0$可以转化为 $sum[r]\% k==sum[l-1]\%k$开个桶维护一 ...
随机推荐
- Linux下安装Sublime Text 3 及使用快捷方式
1.添加sublime text3的仓库 首先按下快捷键ctrl+alt+t打开终端: 在终端输入:sudo add-apt-repository ppa:webupd8team/sublime-te ...
- Salesforce LWC学习(二十五) Jest Test
本篇参看: https://trailhead.salesforce.com/content/learn/modules/test-lightning-web-components https://j ...
- [深入理解JVM虚拟机]第3章-垃圾收集器、内存分配策略
垃圾收集器 判断对象是否需存活 回收堆 判断对象是否存活: 方法一:引用计数法.对象被引用一次就+1,当为0时回收对象.缺点:无法解决循环引用问题. 方法二:可达性分析算法.记录当前对象是否有和GC ...
- 最全总结 | 聊聊 Python 数据处理全家桶(Mysql 篇)
1. 前言 在爬虫.自动化.数据分析.软件测试.Web 等日常操作中,除 JSON.YAML.XML 外,还有一些数据经常会用到,比如:Mysql.Sqlite.Redis.MongoDB.Memch ...
- Windows下使用Nginx+Tomact做负载均衡
前言 今天,王子与大家闲谈一下如何在Windows下使用Nginx+Tomcat做负载均衡的完整步骤,小伙伴们可以试着自己动手实践一下哦. 另外说明一点,本篇文章是纯实操文章,不涉及太多原理的解读,后 ...
- java注解(1)
Java注解是附加在代码中的一些元信息,用于一些工具在编译.运行时进行解析和使用,起到说明.配置的功能.注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用.注解是Java SE5中引入的重要的语言 ...
- k8s&docker面试总结
花了大半个月对k8s&docker进行了梳理,包括之前读过的书,官方文档以及k&d在公司项目的实践等. 以下是个人对docker & k8s 面试知识点的总结: 1 docke ...
- OpenCV计算机视觉学习(1)——图像基本操作(图像视频读取,ROI区域截取,常用cv函数解释)
1,计算机眼中的图像 我们打开经典的 Lena图片,看看计算机是如何看待图片的: 我们点击图中的一个小格子,发现计算机会将其分为R,G,B三种通道.每个通道分别由一堆0~256之间的数字组成,那Ope ...
- Unity 如何在窗口大小可以随意改变的情况下让游戏世界完整的显示在镜头中
当我们开发游戏时,如果是开发手机游戏,屏幕窗口的比例是固定的,不会说在运行时改变的. 但是,PC端的游戏就不一定,我希望它能被用户随意拉扯,但完整的内容还是能显示出来,这里我直接放例子: 请注意黑色的 ...
- PHP正则表达式核心技术完全详解 第1节
作者:极客小俊 一个专注于web技术的80后 我不用拼过聪明人,我只需要拼过那些懒人 我就一定会超越大部分人! CSDN@极客小俊,原创文章, B站技术分享 B站视频 : Bilibili.com 个 ...