题意:

给定一个长度为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. ES6基础入门之let、const

    作者 | Jeskson来源 | 达达前端小酒馆 01 首先呢?欢迎大家来学习ES6入门基础let,const的基础知识内容.初始ECMA Script6. ESMAScript与JavaScript ...

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

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

  3. Zookeeper循环注册监听器

    Zookeeper中的监听器只执行一次,需要在watcher类中重写process方法,以达到重复注册监听器的效果 /** * 连接zk服务器 * */ public static void conn ...

  4. GC(一)内存管理与垃圾回收

    参考文章: 内存分配.GC原理与垃圾收集器:http://www.importnew.com/23035.html g1垃圾回收器:http://blog.jobbole.com/109170/ cm ...

  5. 二叉树 排序二叉树-可以通过中序遍历得到排序的数据 二叉排序树时间复杂度O(logn),

    二叉树是一种非常重要的数据结构,它同时具有数组和链表各自的特点:它可以像数组一样快速查找,也可以像链表一样快速添加.但是他也有自己的缺点:删除操作复杂. 虽然二叉排序树的最坏效率是O(n),但它支持动 ...

  6. FZU Monthly-201909 获奖名单

    FZU Monthly-201909 获奖名单 冠军: 空缺 一等奖: 张咏真 S031802540 孔铖晗 S031802115 二等奖: 苏锦程 S031802325 林柄灿 S031802117 ...

  7. 使用Alibaba的Nacos做为SpringCloud的注册和配置中心,并结合Sentinel+Nocos动态进行限流熔断

    最近在学习阿里的Nacos组件以及Sentinel组件,折腾出了一个小demo. Git地址:https://github.com/yangzhilong/nacos-client 有兴趣的小伙伴可以 ...

  8. CobaltStrike3.14破解

    原文发布在:https://bithack.io/forum/310 8月6日已更新 之前发的是5月2号破解的,并且官方作者的exit暗桩没有去掉.看到很多人用此版本遇到问题,抽空修复了下bug.此版 ...

  9. 阿里巴巴Java开发手册(华山版)

    插件下载地址: https://github.com/alibaba/p3c 2018年9月22日,在2018杭州云栖大会上,召开<码出高效:Java 开发手册>新书发布会,并宣布将图书所 ...

  10. wms证书配置操作

      1. 在应用的/home下 把证书cp到/usr/local/apache2/conf 2. 打开文件/usr/local/apache2/conf/extra/httpd-ssl.conf,找到 ...