[cf 1236 E] Alice and the Unfair Game
题意:
给定一个长度为m的序列$A$,你有一个长度为n的棋盘,可以任选一个位置x作为起点。
在时刻$[1,m+1]$你可以向左或向右移动一格。
设时刻i你移动后所在的位置为$B_i$,你需要满足对于任意$1\leq i\leq m$,$A_{i}\neq B_{i}$。
求有多少对有序数对$(x,y)$,使得以x为起点且以y为终点的合法移动路径存在。
$n,m\leq 10^{5},1\leq A_{i}\leq n$。
题解:
首先观察出一个性质:设x向左最远走到l,向右最远走到r,则$[l,r]$中的位置都可以走到。
为什么呢?我们总可以在不超过m步走到这些位置,然后通过“反复横跳”的操作来躲避$A_{i}$(第m+1步的移动保证了这一点)。
考虑如何求出右边界$r(x)$,首先我们可以按照题意直接走。复杂度为$O(n^2)$貌似自闭。
当什么时候我们这一步走不了呢?设当前时间为t,走到了xt。
那么如果$t$后面的一个$i$能挡住我当且仅当其满足$A_{i}-xt=i-t$。
移个项,$A_{i}-i=xt-t$,那么将这两项视为两个点$(i,A_{i})$和$(t,xt)$,限制条件就相当于他们在同一条斜率为1的直线上。
那么现在就有两种做法,一种是维护这些直线然后$O(n)$线性处理,另外一种是用线段树模拟每一步走的操作。
观察博客的题目可知,我写的是后一种。
考虑在线段树中维护每个点x的位置$pos_{x}$,问题需要我们每次将所有能走的点往右走一步,也就是pos整体+1。
运用lazy标记的思想,我们可以每次仅将不能走的点-1,最后把pos整体+m即可。
如果这样处理的话,那么对于每个限制,(由第一个公式)它影响的就是所有$(pos+lazy)-t=A_{i}-i$的点。
因为增量lazy和t恰好抵消,于是每个限制影响的就是$pos=A_{i}-i$的点。
那么我们直接二分找到这样的一段(注意是一段),然后将其整体-1即可。
最终x的右边界就是$r(x)=seg(x)+m+1$,左边界处理方法类似,但注意移项出来是$A_{i}+i$。
复杂度$O(nlogn)$。
代码:
#include<bits/stdc++.h>
#define maxn 100005
#define maxm 500005
#define inf 0x7fffffff
#define ll long long using namespace std;
ll N,M,A[maxn],B[maxn],tr[maxn<<];
ll R[maxn],L[maxn],lz[maxn<<]; inline ll read(){
ll x=,f=; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
} inline void build(ll l,ll r,ll k){
if(l==r){tr[k]=l;return;}
ll mid=l+r>>;
build(l,mid,k<<);
build(mid+,r,k<<|);
return;
}
inline void add(ll l,ll r,ll x,ll y,ll v,ll k){
if(x<=l && r<=y){lz[k]+=v;return;}
ll mid=l+r>>;
if(x<=mid) add(l,mid,x,y,v,k<<);
if(y>mid) add(mid+,r,x,y,v,k<<|);
return;
}
inline ll query(ll l,ll r,ll p,ll k){
if(l==r) return tr[k]+lz[k];
ll mid=l+r>>;
if(p<=mid) return query(l,mid,p,k<<)+lz[k];
else return query(mid+,r,p,k<<|)+lz[k];
} int main(){
N=read(),M=read();
for(ll i=;i<=M;i++) A[i]=read();
if(N==){cout<<""<<endl;return ;}
build(,N,);
for(ll i=;i<=M;i++){
ll l=,r=N,ansl=,ansr=;
while(l<=r){
ll mid=l+r>>;
if(query(,N,mid,)<A[i]-i) ansl=mid,l=mid+;
else r=mid-;
}
ansl++,l=,r=N;
while(l<=r){
ll mid=l+r>>;
if(query(,N,mid,)<=A[i]-i) ansr=mid,l=mid+;
else r=mid-;
}
if(ansl<=ansr) add(,N,ansl,ansr,-,);
}
for(ll i=;i<=N;i++) R[i]=min(query(,N,i,)+M+,N);
memset(tr,,sizeof(tr));
memset(lz,,sizeof(lz));
build(,N,);
for(ll i=;i<=M;i++){
ll l=,r=N,ansl=,ansr=;
while(l<=r){
ll mid=l+r>>;
if(query(,N,mid,)<A[i]+i) ansl=mid,l=mid+;
else r=mid-;
}
ansl++,l=,r=N;
while(l<=r){
ll mid=l+r>>;
if(query(,N,mid,)<=A[i]+i) ansr=mid,l=mid+;
else r=mid-;
}
if(ansl<=ansr) add(,N,ansl,ansr,,);
}
for(ll i=;i<=N;i++) L[i]=max(query(,N,i,)-M-,1ll*);
ll ans=;
for(ll i=;i<=N;i++) ans+=R[i]-L[i]+;
cout<<ans<<endl;
return ;
}
E
[cf 1236 E] Alice and the Unfair Game的更多相关文章
- E. Alice and the Unfair Game(推导线段树)
题:https://codeforces.com/contest/1236/problem/E 粗自:https://www.cnblogs.com/YSFAC/p/11715522.html #in ...
- Codeforces 1236E. Alice and the Unfair Game
传送门 首先可以注意到对于固定的起点 $S$ ,它最终能走到的终点一定是一段区间 这个用反证法容易证明,假设合法区间存在断点,这个点左右都可以作为终点 那么分成区间断点在起点左边和起点右边讨论一下即可 ...
- Codeforces Round #593 (Div. 2)
传送门 A. Stones 签到. B. Alice and the List of Presents 单独考虑每个数的贡献即可. 答案为\((2^{m}-1)^n\). C. Labs 构造就类似于 ...
- cf C. Alice and Bob
http://codeforces.com/contest/347/problem/C 这道题就是求出n个数的最大公约数,求出n个数的最大值,总共有max1/gcd-n个回合.然后判断如果回合数%2= ...
- (中等) CF 585C Alice, Bob, Oranges and Apples,矩阵+辗转相除。
Alice and Bob decided to eat some fruit. In the kitchen they found a large bag of oranges and apples ...
- CF6C Alice, Bob and Chocolate
CF6C Alice, Bob and Chocolate 题目链接 写了一天搜索写的有点累了,就顺手水了一道CF的模拟题 这道题就是简单的模拟整个题的过程,注意最后输出的形式就好了QWQ AC代码如 ...
- CF #575 Div3
// 比赛链接:https://codeforces.com/contest/1196 // CF 2019.7.24 // 本想Div3手速场上分,结果卡在C题,掉了不少分. // 自闭了这么久,今 ...
- A - Alice and the List of Presents (排列组合+快速幂取模)
https://codeforces.com/contest/1236/problem/B Alice got many presents these days. So she decided to ...
- [cf]Codeforces Round #784(Div 4)
由于一次比赛被虐得太惨,,生发开始写blog的想法,于是便有了这篇随笔(找了个近期的cf比赛练练手(bushi))第一次写blog,多多包涵. 第二场cf比赛,第一场打的Div2,被虐太惨,所以第二场 ...
随机推荐
- mark一下咕掉的题目
蒟蒻才普及组呀~ 大佬别D我 等集中补一下 CF980F:咋说捏,我觉得要联赛了做这题有点浪费时间,等想颓废了再来写写叭qwq 215E/279D/288E/331C3/431D/433E/750G/ ...
- mfs分布式文件系统,分布式存储,高可用(pacemaker+corosync+pcs),磁盘共享(iscsi),fence解决脑裂问题
一.MFS概述 MooseFS是一个分布式存储的框架,其具有如下特性:(1)通用文件系统,不需要修改上层应用就可以使用(那些需要专门api的dfs很麻烦!).(2)可以在线扩容,体系架构可伸缩性极强. ...
- limma 包
limma:Linear Models for Microarray and RNA-Seq Data http://www.bioconductor.org/packages/release/bio ...
- 联想M7216NWA墨粉清零:
在设备就绪状态下,按"功能"键,进入设置菜单,按上下键进行选择,屏幕出现"设备信息"项时按"确认"键,再按上下键选择,当屏幕出现" ...
- Zabbix实战-简易教程--中间件kafka监控
一.环境准备 1.安装kafka Step 1: 下载代码 你可以登录Apache kafka 官方下载.http://kafka.apache.org/downloads.html备注:2.11-1 ...
- 【Python】[技术博客] 如何对使用PYQT编写的GUI文件进行单元测试
如何对使用PYQT编写的GUI文件进行单元测试 想要对PYQT编写的GUI文件进行单元测试,我们主要用到QTest QTest里面包含了一些对窗体的各种控件进行模拟操作的函数,通过QTest对窗体进行 ...
- yum -y install pip No package pip available. Error: Nothing to do
centos下安装pip时失败: [root@wfm ~]# yum -y install pipLoaded plugins: fastestmirror, refresh-packagekit, ...
- quartus仿真提示: Can't launch the ModelSim-Altera software
quartus仿真提示: Can't launch the ModelSim-Altera software 2017年07月13日 17:54:50 小怪_tan 阅读数:3255 路径中的结尾 ...
- git 常用命令的总结
1. git 查看分支 git branch (星号代表当前的分支) 2. 创建一个本地分支 git checkout -b 分支名称 3. 将本地新建分支提交到远程 git push origin ...
- android mk 预编译库
LOCAL_PATH := $(call my-dir) #include $(CLEAR_VARS) # OpenCV #OPENCV_CAMERA_MODULES:=on #OPENCV_INST ...