Description

有一个长度为n的数组a,现在要找一个长度至少为2的子段,求出这一子段的和,然后减去最大值,然后对k取余结果为0。
问这样的子段有多少个
题面

Solution

考虑分治,普遍的做法就是用最大值分治:即找到最大值作为 \(mid\),然后 \(solve(l,mid),solve(mid+1,r)\)
但是这样做必须得保证每一次枚举 \(mid-l\)和\(r-mid\) 中最小的一个才能保证复杂度,即启发式合并的复杂度 \(O(n*logn)\)

从上往下递归的话,每一次找最大值是一个复杂度瓶颈,考虑从下往上,每一次合并最大值即可

这个过程可以不用递归实现,我们按照从小到大的顺序枚举 \(a\) 中的每一个数,并且维护分治区间 \([L,R]\) 就可以达到这个效果
\([L,R]\) 的实际含义就是 \(mid\) 是 \([L,R]\) 中的最大值

考虑 \(solve(l,r)\) 怎么统计答案,我们枚举 \(mid-l\) 和 \(r-mid\) 中较小的一个 \(i\),那么 \(i\) 的贡献就是在 \([l,mid]\) 中与 \(sum[i]\) 相同的数的个数
\(sum\) 是模 \(k\) 意义下的前缀和,对于每一个 \(sum[i]\) 我们开一个数组(维护相同前缀和出现的不同位置),二分出 \([l,mid]\) 中出现的次数,就做完了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=300005;
vector<int>S[1000005];
int n,K,a[N],s[N],L[N],R[N],lis[N];ll ans=0;
inline bool comp(int i,int j){return a[i]<a[j];}
inline int query(int l,int r,int k){if(l>r)return 0;return upper_bound(S[k].begin(),S[k].end(),r)-upper_bound(S[k].begin(),S[k].end(),l-1);
}
inline void solve(int mid){int l=L[mid]+1,r=R[mid]-1;if(mid-l<r-mid){for(int i=l-1;i<mid;i++)ans+=query(max(mid,i+2),r,(s[i]+a[mid])%K);}else{for(int i=mid;i<=r;i++)ans+=query(l-1,min(mid-1,i-2),(s[i]-a[mid]+K)%K);}R[L[mid]]=R[mid];L[R[mid]]=L[mid];
}
int main(){freopen("pp.in","r",stdin);freopen("pp.out","w",stdout);scanf("%d%d",&n,&K);for(int i=1;i<=n;i++){scanf("%d",&a[i]);s[i]=(s[i-1]+a[i])%K;L[i]=i-1;R[i]=i+1;}for(int i=0;i<=n;i++)S[s[i]].push_back(i),lis[i]=i;sort(lis+1,lis+n+1,comp);for(int i=1;i<=n;i++)a[lis[i]]%=K,solve(lis[i]);cout<<ans<<endl;return 0;
}

转载于:https://www.cnblogs.com/Yuzao/p/8503763.html

Codeforces 549F Yura and Developers相关推荐

  1. codeforces 549F Yura and Developers(分治、启发式合并)

    codeforces 549F Yura and Developers 题意 给定一个数组,问有多少区间满足:去掉最大值之后,和是k的倍数. 题解 分治,对于一个区间,找出最大值之后,分成两个区间. ...

  2. ●CodeForces 549F Yura and Developers

    题链: http://codeforces.com/problemset/problem/549/F 题解: 分治,链表. 考虑对于一个区间[L,R],其最大值在p位置, 那么答案的贡献就可以分为3部 ...

  3. [分治] 51Nod1472 Codeforces #549F. Yura and Developers

    分治学傻的我只会无脑分治-- 题意就是求满足 sum≡maxsum \equiv max 的区间.反正就是按套路搞. 注意计数的数组不能每次 clearclear ,要开时间戳. #include&l ...

  4. Codeforces - Yura and Developers

    题目链接:Codeforces - Yura and Developers 有一个显然的2个log做法. 分治最大值,然后枚举小区间启发式计算答案. 但是其实可以一个log,因为分治的时候,对于区间形 ...

  5. 【Codeforces549F】Yura and Developers [单调栈][二分]

    Yura and Developers Time Limit: 20 Sec  Memory Limit: 512 MB Description Input Output Sample Input 4 ...

  6. Yura and Developers

    Yura and Developers 题目大意 给出一个长度为n的区间,求其中有多少个区间,使得这个区间中所有元素的和减去这个区间中的最大值除以k的余数为0. 代码 #include<cstd ...

  7. Looksery Cup 2015 F - Yura and Developers 单调栈+启发式合并

    F - Yura and Developers 第一次知道单调栈搞出来的区间也能启发式合并... 你把它想想成一个树的形式, 可以发现确实可以启发式合并. #include<bits/stdc+ ...

  8. 【Codeforces 549F】Yura and Developers | 单调栈、启发式合并、二分

    题目链接:https://codeforces.com/problemset/problem/549/F 题目大意: 给定一个序列和一个mod值,定义[l,r]合法当l到r的所有元素和减去其中的最大值 ...

  9. [CF549F/51nod1472]Yura and Developers

    题目大意 有一个长度为n的数组a,现在要找一个长度至少为2的子段,求出这一子段的和,然后减去最大值,然后对k取余结果为0. 问这样的子段有多少个. 数据范围 1 ≤ n ≤ 300 000, 1 ≤  ...

最新文章

  1. Scrapy爬虫及案例剖析
  2. encoder-decoder 注意力机制整理名望所
  3. 机器学习加深了“知识”和“理解”之间的鸿沟
  4. python打破循环_python – 为什么“c.execute(…)”打破循环?
  5. 辽宁省风力发电行业“十四五”前景规划及竞争策略分析报告2022-2028年版
  6. 轻松理解spring IOC
  7. JsonData响应工具类封装
  8. 女博士年薪156万入职华为!实力演绎美貌与智慧并重
  9. 大数据_MapperReduce_与hive的集成_使用hive数据分析工具_关联操作hbase---Hbase工作笔记0025
  10. 数据库知识点一共涉及这几方面知识
  11. paip.php 配置ZEND DEBUGGER 断点调试for cli..
  12. MySQL-JDBC
  13. ArcEngine合并要素
  14. 人体姿态检测——CPN
  15. html等待,休眠代码,HTML DOM closest()用法及代码示例
  16. 定积分的基本性质6 积分第一中值定理
  17. 【华人学者风采】谭平 阿里人工智能实验室
  18. [导入]雨音唱片-《音乐诗画 4CD》四季系列 320k/mp3(亲传)
  19. Python3 浮点数精度问题
  20. 深度学习中的 BN (BatchNormalization)理解

热门文章

  1. server多笔记录拼接字符串 sql_sqlserver 将多行数据查询合并为一条数据
  2. HDU 5643 King's Game 打表
  3. 20X20 FCPX插件数字信息化故障干扰像素损坏风格英文标题模板GlitchAnimatedTypeface
  4. error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include “pch.h“
  5. 爱情里没有谁对谁错 - 郑源
  6. Kid的某些跳刺套路
  7. java之利用行列式展开法,计算行列式的值
  8. DIV布局 旅游出行网站设计——武汉旅游(11页) HTML+CSS+JavaScript dreamweaver作业静态HTML网页设计模板
  9. 《缠中说禅108课》49:利润率最大的操作模式
  10. 一种与生活周旋的能力