题意:

给定一个长度为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的更多相关文章

  1. E. Alice and the Unfair Game(推导线段树)

    题:https://codeforces.com/contest/1236/problem/E 粗自:https://www.cnblogs.com/YSFAC/p/11715522.html #in ...

  2. Codeforces 1236E. Alice and the Unfair Game

    传送门 首先可以注意到对于固定的起点 $S$ ,它最终能走到的终点一定是一段区间 这个用反证法容易证明,假设合法区间存在断点,这个点左右都可以作为终点 那么分成区间断点在起点左边和起点右边讨论一下即可 ...

  3. Codeforces Round #593 (Div. 2)

    传送门 A. Stones 签到. B. Alice and the List of Presents 单独考虑每个数的贡献即可. 答案为\((2^{m}-1)^n\). C. Labs 构造就类似于 ...

  4. cf C. Alice and Bob

    http://codeforces.com/contest/347/problem/C 这道题就是求出n个数的最大公约数,求出n个数的最大值,总共有max1/gcd-n个回合.然后判断如果回合数%2= ...

  5. (中等) 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 ...

  6. CF6C Alice, Bob and Chocolate

    CF6C Alice, Bob and Chocolate 题目链接 写了一天搜索写的有点累了,就顺手水了一道CF的模拟题 这道题就是简单的模拟整个题的过程,注意最后输出的形式就好了QWQ AC代码如 ...

  7. CF #575 Div3

    // 比赛链接:https://codeforces.com/contest/1196 // CF 2019.7.24 // 本想Div3手速场上分,结果卡在C题,掉了不少分. // 自闭了这么久,今 ...

  8. A - Alice and the List of Presents (排列组合+快速幂取模)

    https://codeforces.com/contest/1236/problem/B Alice got many presents these days. So she decided to ...

  9. [cf]Codeforces Round #784(Div 4)

    由于一次比赛被虐得太惨,,生发开始写blog的想法,于是便有了这篇随笔(找了个近期的cf比赛练练手(bushi))第一次写blog,多多包涵. 第二场cf比赛,第一场打的Div2,被虐太惨,所以第二场 ...

随机推荐

  1. WeUI框架

    WeUI框架 WeUI是一套小程序的UI框架,所谓UI框架就是一套界面设计方案,有了组件,我们可以用它来拼接出一个内容丰富的小程序,而有了UI框架,我们就可以让我们的小程序变得更加美观. 体验WeUi ...

  2. [golang][hugo]使用Hugo搭建静态站点

    使用Hugo搭建静态站点 hugo下载地址:https://github.com/gohugoio/hugo 模板列表:https://github.com/gohugoio/hugoThemes 开 ...

  3. go语言Mac下编译安装语言包

    这两天公司成立了go语言学习兴趣小组,慕名参与了学习.目前对于go是0基础,只知道它可以做高并发.效率快.编译简单.母语是C. go的安装有多种形式,编译安装是比较慢的一个,今天我就记录一下学习go编 ...

  4. zabbix监控nginx,mysql,java

    zabbix 支持的主要监控方式(1)agent代理程序 在Agent监控方式下,zabbix-agent会主动收集本机的监控信息并通过TCP协议与zabbix-server传递信息.Agent 监控 ...

  5. jvm(三)指令重排 & 内存屏障 & 可见性 & volatile & happen before

    参考文档: https://tech.meituan.com/java-memory-reordering.html http://0xffffff.org/2017/02/21/40-atomic- ...

  6. 从太空到地球某个位置的轨迹录像制作 | Earth Zoom in/out Tutorial (Record Video)

    视频教程:Google Earth - Earth Zoom in/out Tutorial (Record Video) 下载google earth 在search里输入你想要去的地名 zoom ...

  7. 解决window的bat脚本执行出现中文乱码的问题

    window下通过新建txt文件然后改成.bat的文件,输入内容后,执行出现中文乱码?原因: 批处理文件,是以ANSI编码方式.若以别的方式(如UTF-8)编辑了批处理,转换成ANSI格式即可,正常创 ...

  8. Nodejs 包与 npm第三方模块安装和 package.json 以及 cnpm

    包与 NPM 1. 包 Nodejs 中除了它自己提供的核心模块外,可以自定义模块,也可以使用第三方的模块.Nodejs 中第三方模块由包组成,可以通过包来对一组具有相互依 赖关系的模块进行统一管理. ...

  9. xgboost 算法总结

    xgboost有一篇博客写的很清楚,但是现在网址已经失效了,之前转载过,可以搜索XGBoost 与 Boosted Tree. 现在参照这篇,自己对它进行一个总结. xgboost是GBDT的后继算法 ...

  10. c++ Array运用实例

    myprint.hpp #include <iostream> #include <string> template <typename T> inline voi ...