联赛%你测试10T2:漫无止境的八月
题意:

思路:
有几个特殊的性质:
- 在不考虑q里面的单点修改,我们先只判断一个序列是否Yes。
- 我们注意到每次操作都是对一个长度为k的区间进行区间加减1的操作,所以我们如果将序列里面的数按%k分组,把同一组的数都加在一起,那每次操作就一定是给每一个组都加上或减去一个1,因为连续的k长度中,一定是每一组都有且只有一个数受到处理。
- 因为我们自己的操作是区间加减,那么操作是可逆的,如果这个序列能变成全0的序列,那么他也一定可以由全0的序列转移过来,全0的序列每一组的和都是0,进行几次操作后,只会给每一组都加上或减去一些1。所以如果一个序列可以由全0序列转移来,那么它每一组数的和都一定相等。
- 加上单点修改后,会有什么改变呢?
- 很显然,会改变某一组的和。
- 如果改变后所有组的和都相等,那么输出Yes,否则输出No
- 这样\(O(n)\)查询显然不行,那我们稍微优化下。
- 我们开个桶,记录某一个值出现了几次,如果一个组的和是x,那么vis[x]++;如果一个值的vis是k,那么就说明所有组的和都一样,那么就输出yes啦。
- 在修改的时候,我们把修改前的这组和的vis值--,修改后的这组和vis值++,然后判断就好啦。
然后就完了吗???
当然不,区间和的值太大了,数组开不下。
有人会说:用map呀,map开的下。
map常数巨大,直接T飞(70分)。
- 有人会说:用unordered_map呀,O(1)查询总没问题吧
- 评测机没开c++11,根本用不了。
- unordered_map实测也会T。
- 所以这道题想通过这种方法a掉,就只剩两种方法了:
- 运用神仙快读fread()+强行预编译c++11
- 手打哈希表。
就没别的办法了吗???
当然有。
我们考虑差分(区间问题的一种可行性方法),先建出来差分数组。
每次修改是对i加一个值对i+k减去同一个值。
那我们再按%k分组求和,发现无论如何更改,每一组的和都是不变的(因为i和i+k在一组里)。
因为全0序列的差分数组每一组的和都是0,那么只要一个序列每一组和都是0,那就Yes。
一个特判:
我们发现原序列的最后一段区间n-k+1~n,通过差分数组的处理,是给n-k+1的位置上加一个值,再给n+1的位置上减一个值。但是n+1位置上是没有数的。所以我们得出一个惊人的事实:
n+1所在那个组的和是随便选的!!!
因为你修改这个组的数的时候,因为n+1这个位置上没有数,那就是随便选,那当然无论怎样这组的和都可以看作0。
我自己的口胡证明:
n+1这一组之所以特殊,是因为这一组的最后一项chafen[n-k+1]的修改比较特殊,我们在处理原序列的最后一段n-k+1~n这一段时候,对应到差分数组上是只给chafen[n-k+1]进行加减的,而其他的区间都是前面加上一个,后面再减回去一个。所以我们可以认为,无论原序列如何,可以做到只更改chafen[n-k+1]而不对其他的差分数组的值产生影响,那么无论这一组差分数组的和是多少,我们可以通过人为调控chafen[n-k+1]的值使得这一组的和最后变为0。因此,这一组的和是任取的。
所以询问一个区间是否Yes,只要看它差分后的所有组(除了n+1那组)是不是和都是0即可。
我的做法deepinc&skyh学长的处理方法是:
- 先扫一遍给的序列,算出差分数组。记录每组和,如果有某组和不是0,那么cnt++。如果扫完后cnt==0就Yes否则就No。(需特判n+1%k这组)
- 每次单点修改,就是对pos所在的组加上一个数,对pos+1所在的组减去一个数(差分数组的性质)
- 如果有一个组的和由非0变成了0那么cnt--,如果一个组的和由0变成了非0,那么cnt++。每一个修改过后,直接看cnt==0就Yes。(注意:如果pos或pos+1所在的组有在n+1%k那组的,那这一组就不用处理上面的这些了)
附上丑码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e6+10;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
int a[maxn],chafen[maxn],num[maxn];
int n,k,q;
int main(){
freopen("august.in","r",stdin);
freopen("august.out","w",stdout);
n=read();k=read();q=read();
for(register int i=1;i<=n;i++){
a[i]=read();
}
for(register int i=1;i<=n;i++){
chafen[i]=a[i]-a[i-1];
}
for(register int i=1;i<=n;i++){
num[i%k]+=chafen[i];
}
int ignore=(n+1)%k;
int cnt=0;
for(register int i=0;i<k;i++){
if(num[i]){
cnt++;
}
}
if(num[ignore])cnt--;
if(!cnt)puts("Yes");else puts("No");
for(register int i=1;i<=q;i++){
int pos,x;
pos=read();
x=read();
if(pos%k!=ignore){
if(num[pos%k]==0&&num[pos%k]+x!=0)cnt++;
if(num[pos%k]!=0&&num[pos%k]+x==0)cnt--;
num[pos%k]+=x;
}
if((pos+1)%k!=ignore){
if(num[(pos+1)%k]==0&&num[(pos+1)%k]-x!=0)cnt++;
if(num[(pos+1)%k]!=0&&num[(pos+1)%k]-x==0)cnt--;
num[(pos+1)%k]-=x;
}
if(!cnt)puts("Yes");else puts("No");
}
return 0;
}
联赛%你测试10T2:漫无止境的八月的更多相关文章
- csps模拟9495凉宫春日的忧郁,漫无止境的八月,简单计算,格式化,真相题解
题面:https://www.cnblogs.com/Juve/articles/11767239.html 94,95的T3都没改出来,是我太菜了... 凉宫春日的忧郁: 比较$x^y$和$y!$的 ...
- 联赛模拟测试5 涂色游戏 矩阵优化DP
题目描述 分析 定义出\(dp[i][j]\)为第\(i\)列涂\(j\)种颜色的方案数 然后我们要解决几个问题 首先是求出某一列涂恰好\(i\)种颜色的方案数\(d[i]\) 如果没有限制必须涂\( ...
- 联赛模拟测试8 Dash Speed 线段树分治
题目描述 分析 对于测试点\(1\).\(2\),直接搜索即可 对于测试点\(3 \sim 6\),树退化成一条链,我们可以将其看成序列上的染色问题,用线段树维护颜色相同的最长序列 对于测试点\(7\ ...
- 联赛模拟测试10 C. 射手座之日
题目描述 分析 方法一(线段树) 线段树维护的是以当前节点为左端点的区间的贡献 而区间的右端点则会从 \(1\) 到 \(n\) 逐渐右移 当我们把右端点从 \(i-1\) 的位置扩展到 \(i\) ...
- 联赛模拟测试12 C. sum 莫队+组合数
题目描述 分析 \(80\) 分的暴力都打出来了还是没有想到莫队 首先对于 \(s[n][m]\) 我们可以很快地由它推到 \(s[n][m+1]\) 和 \(s[n][m-1]\) 即 \(s[n] ...
- 联赛模拟测试12 B. trade
题目描述 分析 \(n^2\) 的 \(dp\) 应该比较好想 设 \(f[i][j]\) 为当前在第 \(i\) 天剩余的货物数量为 \(j\) 时的最大收益 那么它可以由 \(f[i-1][j]\ ...
- 联赛模拟测试14 A. 虎
题目描述 这题太虎了,所以没有背景. 给你一棵树,边有黑白两种颜色,你每次可以选择两个点,把这两个点之间的唯一简单路径上的所有边颜色取反,某些边要求最终颜色必须是黑色,还有些边没有要求,问最少操作多少 ...
- 联赛模拟测试17 A. 简单的区间 启发式合并
题目描述 分析 我们要找的是一段区间的和减去该区间的最大值能否被 \(k\) 整除 那么对于一段区间,我们可以先找出区间中的最大值 然后枚举最大值左边的后缀与最大值右边的前缀之和是否能被 \(k\) ...
- 联赛模拟测试18 A. 施工 单调队列(栈)优化DP
题目描述 分析 对于 \(Subtask\ 1\),可以写一个 \(n^3\) 的 \(DP\),\(f[i][j]\) 代表第 \(i\) 个建筑高度为 \(j\) 时的最小花费,随便转移即可 时间 ...
随机推荐
- apply用法
result.push.apply(result, document.getElementsByTagName(tag)); 但是,这里为什么要用apply呢? 因为document.getEleme ...
- Linux驱动之GPIO子系统和pinctrl子系统
前期知识 1.如何编写一个简单的Linux驱动(一)--驱动的基本框架 2.如何编写一个简单的Linux驱动(二)--设备操作集file_operations 3.如何编写一个简单的Lin ...
- js中模拟移动端长按效果
我们都知道 js 是有onmousedown(鼠标按下事件)和onmouseup(鼠标抬起事件),刚开始我的思路是 鼠标抬起时间减去鼠标按下时间 var oDiv = document.getElem ...
- 学习 | css3基本动画之demo篇
移动端使用的框架是zepto,但是zepto的内置对象没有传统的animate这个方法,效果都是需要css3来实现的,zepto也不支持fadeIn和fadeOut等一些基本的动画,基于这一现状,我自 ...
- SSO单点登录可以自己实现吗?--开源软件诞生10
ERP与SSO的恩怨情仇--第10篇 用日志记录“开源软件”的诞生 赤龙 ERP 开源地址: 点亮星标,感谢支持,与开发者交流 kzca2000 码云:https://gitee.com/redrag ...
- TS数据类型:类型别名/联合类型/字面量类型/类型推论等纲要
在学C/C++ Java等强类型语言时,变量类型是唯一的,需要先指定.PHP JavaScript等弱类型语言时,无需指定变量类型 但是,TypeScript里面的联合类型 (Union Type) ...
- Kubernetes入门(四)——如何在Kubernetes中部署一个可对外服务的Tensorflow机器学习模型
机器学习模型常用Docker部署,而如何对Docker部署的模型进行管理呢?工业界的解决方案是使用Kubernetes来管理.编排容器.Kubernetes的理论知识不是本文讨论的重点,这里不再赘述, ...
- linux操作指南-01
目录 1.1 MBR 1.2 装双系统的坑 1.3 主机硬盘的主要规划 前言:记录下最近在看的鸟哥Liunx私房菜,虽然不是第一次看了..想记录几章开发中用的比较多的部分大致是以下几个章节 第3章 主 ...
- 01.vue数据绑定
Vue特点 渐进式: 渐进, 可以理解成一步一步的. 在使用Vue的时候, 我们不需要把整个Vue框架的东西都用上, 可以一步一步的根据需要慢慢的替换之前的代码. 自底向上逐层应用: 由底层开始, 把 ...
- c#RSA的SHA1加密与AES加密、解密
前言:公司项目对接了一个对数据保密性要求较高的java公司.api接口逻辑是这样的:他们提供 SHA1私钥 与 AES的秘钥.我们需要将 传递查询参数 通过SHA1 私钥加密再转换成 十六进制 字符串 ...