Description

小南有一套可爱的玩具小人,它们各有不同的职业。

有一天,这些玩具小人把小南的眼镜藏了起来。小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外。如下图:

这时 singer 告诉小南一个谜题:“眼镜藏在我左数第 3 个玩具小人的右数第 1 个玩具小人的左数第 2 个玩具小人那里。”

小南发现,这个谜题中玩具小人的朝向非常关键,因为朝内和朝外的玩具小人的左右方向是相反的: 面朝圈内的玩具小人,它的左边是顺时针方向,右边是逆时针方向;而面向圈外的玩具小人,它的左边是逆时针方向,右边是顺时针方向。

小南一边艰难地辨认着玩具小人,一边数着:

“singer 朝内,左数第 3 个是 archer。

“archer 朝外,右数第 1 个是 thinker。

“thinker 朝外,左数第 2 个是 writer。

“所以眼镜藏在 writer 这里!”

虽然成功找回了眼镜,但小南并没有放心。如果下次有更多的玩具小人藏他的眼镜,或是谜题的长度更长,他可能就无法找到眼镜了。为了解决问题,他决定让他的玩具小人互相战斗,杀死对方,以减少玩具小人的数量,这样就不会有那么多麻烦了。

小南一共有N个玩具小人,每个玩具小人有一个战斗力,小南会把一些玩具小人染成红色(也可以不选,也就是全部染成蓝色;也可以全部染成红色),剩下的都染成蓝色,让红色方和蓝色方互相战斗(其中一方可以为空)。

当同一方的两个玩具小人的战斗力差距过大时,他们之间会产生矛盾。为了有效减少玩具小人的数量,小南希望他的玩具小人之间尽可能地产生矛盾。因此,任意两个不同的红色玩具小人的战斗力之差必须大于等于一个给定的数A,而任意两个不同的蓝色玩具小人的战斗力之差则必须大于等于另一个给定的数B。

小南想知道有多少可能的染色方案,使得同一方的玩具小人两两之间都会产生矛盾。请你写一个程序帮他统计所有可能的方案的总数,数值对109+7取模。

Input

输入第一行包含三个数N,A,B。
接下来N行中,第i行包含一个整数ai,表示第i个玩具小人的战斗力。

Output

输出染色方案数对109+7取模后的值。
Sample Input

Sample Input 1

5 3 7
1
3
6
9
12

Sample Input 2

7 5 3
0
2
4
7
8
11
15

Sample Input 3

8 2 9
3
4
5
13
15
22
26
32

Sample Input 4

3 3 4
5
6
7
Sample Output

Sample Output 1

5

Sample Output 2

4

Sample Output 3

13

Sample Output 4

0

HINT

在第一个样例中,记红色小人集合为X,蓝色为Y,则有一下5种染色方案:

  1. X={1,6,9,12},Y={3}
  2. X={1,6,9},Y={3,12}
  3. X={3,6,9,12},Y={1}
  4. X={3,6,9},Y={1,12}
  5. X={3,6,12},Y={1,9}

数据范围:
1≤N≤105
1≤A,B≤1018
0≤ai≤1018
ai<ai+1(1≤i<N)

存在30分的子任务,满足1≤N≤2000。

思路

首先考虑O(n2)的做法:

为了方便,我们令a0=−∞

设fM,i,j(M∈{X,Y},1≤i≤n,0≤j<i)表示已划分好S1⋯i且Sj是最后一个不属于M的元素的方案数

已算好fX,1⋯i,j和fY,1⋯i,j,如何转移?

①若ai+1−ai≥A,Si+1可被放入X中,则fX,i+1,0⋯i−1=fX,i,0⋯i−1

否则ai,ai+1不可一起被放入X中,fX,i+1,0⋯i−1=0

②显然fY,i+1,i=∑j=0i−1[ai+1−Sj≥B]fX,i,j

对fY的处理相似

最后的答案就是∑i=0n−1fX,n,i+∑i=0n−1fY,n,i

考虑优化

首先将a升序排序

因为a是递增的,所以满足ai+1−aj≥B的Sj一定是一段前缀,所以我们可以用二分找到右端点并用线段树求区间和

其他转移就相当于线段树的单点更新

代码

#include<bits/stdc++.h>
#define ll long long
#define mod 1000000007
using namespace std;
const int N=1e5+77;
int sumx[N*4],sumy[N*4],lazx[N*4],lazy[N*4],*laz,*sum,n;
ll a[N];
void pushdown(int x)
{if(laz[x]){laz[x<<1]=laz[x<<1|1]=1;sum[x<<1]=sum[x<<1|1]=0;laz[x]=0;}
}
int query(int st,int ed,int l,int r,int x)
{if(st<=l&&r<=ed)return sum[x];pushdown(x);int mid=(l+r)>>1,ans=0;if(st<=mid)ans=(ans+query(st,ed,l,mid,x<<1))%mod;if(mid<ed)ans=(ans+query(st,ed,mid+1,r,x<<1|1))%mod;return ans;
}
void add(int pos,int v,int l,int r,int x)
{if(l==r){sum[x]=(sum[x]+v)%mod; return;}pushdown(x);int mid=(l+r)>>1;if(pos<=mid) add(pos,v,l,mid,x<<1);else add(pos,v,mid+1,r,x<<1|1);sum[x]=(sum[x<<1]+sum[x<<1|1])%mod;
}
int queryx(int st,int ed)
{laz=lazx; sum=sumx;return query(st,ed,0,n-1,1);
}
void addx(int pos,int v)
{laz=lazx; sum=sumx;add(pos,v,0,n-1,1);
}
int queryy(int st,int ed)
{laz=lazy; sum=sumy;return query(st,ed,0,n-1,1);
}
void addy(int pos,int v)
{laz=lazy; sum=sumy;add(pos,v,0,n-1,1);
}
int main()
{ll A,B;scanf("%d%lld%lld",&n,&A,&B);for(int i=1; i<=n; i++)scanf("%lld",&a[i]);sort(a+1,a+n+1);a[0]=-4223372036854775807ll;addx(0,1); addy(0,1);for(int i=1; i<n; i++){int l=0,r=i-1,x=0;while(l<=r){int mid=(l+r)>>1;if(a[i+1]-a[mid]>=B) x=mid,l=mid+1;else r=mid-1;}int t1=queryx(0,x);l=0; r=i-1;while(l<=r){int mid=(l+r)>>1;if(a[i+1]-a[mid]>=A) x=mid,l=mid+1;else r=mid-1;}int t2=queryy(0,x);if(a[i+1]-a[i]<A){sumx[1]=0; lazx[1]=1;}if(a[i+1]-a[i]<B){sumy[1]=0; lazy[1]=1;}addy(i,t1); addx(i,t2);}printf("%d",(queryx(0,n-1)+queryy(0,n-1))%mod);
}

【gdgzezoi】Problem A: 玩具谜题相关推荐

  1. 信息学奥赛真题解析(玩具谜题)

    玩具谜题(2016年信息学奥赛提高组真题) 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业.有一天, 这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的 ...

  2. 简单 洛谷 P1563 【模拟】玩具谜题普及场

    ** 简单 洛谷 P1563 [模拟]玩具谜题普及场** 小南有一套可爱的玩具小人, 它们各有不同的职业. 有一天, 这些玩具小人把小南的眼镜藏了起来. 小南发现玩具小人们围成了一个圈,它们有的面朝圈 ...

  3. noip2016玩具谜题

    玩具谜题 嗯,再次上课耍了一个春节好久都没写博客了 ,先来一篇水题题解 附上连接: (传送门)洛谷 题目描述: 这个题一眼看出没有什么难度,只是纯粹的模拟,我们只需要看小人面向哪里,再往那个方向数人就 ...

  4. 洛谷 P1563 玩具谜题

    这里给出题目的链接洛谷 P1563 玩具谜题 分析题目,很明显可以知道人物可以用数字来表示,将人物的名字单独存在一个数组里面,获取最终人物对应的数字后,即可输出人物的名称,即这道题的答案. 这道题可以 ...

  5. 2556. [NOIP2016]玩具谜题

    [题目描述] 小南有一套可爱的玩具小人,它们各有不同的职业.有一天,这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝国内,有的面朝圈外.如下图: 这时singer告诉小南 ...

  6. 【模拟】P1563 玩具谜题

    https://www.luogu.com.cn/problem/P1563 考点:模拟.高性能 题意: 题目太长,就不全贴了.大意是有n个玩具小人围成一个圈,可能朝向圈内或圈外.接下来m条指令指引我 ...

  7. 牛客16426 玩具谜题

    题目描述 南有一套可爱的玩具小人,它们各有不同的职业. 有一天,这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外,如下图: 这时 singer 告诉小南 ...

  8. 玩具谜题(洛谷-P1563)

    题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业. 有一天, 这些玩具小人把小南的眼镜藏了起来. 小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外.如下图: 这时singer告诉 ...

  9. 模拟——玩具谜题(洛谷 P1563)

    模拟算法指的是让程序完整地按照题目叙述的方式运行得到答案! 此题选自洛谷P1563 简单的模拟,类似约瑟夫问题的部分,采用取余的方式. 需要注意的是朝向问题,用一个结构体来保存每个人的朝向即可. 题目 ...

最新文章

  1. [译]从零开始成为数据科学家的9个步骤
  2. OpenGL之矩阵变换的原理分析与数学推导
  3. 前端学习(1911)vue之电商管理系统电商系统之完成用户的修改弹框询问用户是否删除
  4. 在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新。
  5. rust里面的awm叫什么_铅笔里面有铅吗?为什么叫铅笔呢?
  6. docker进阶与实战 3 理解docker镜像
  7. c语言实训项目,C语言项目实训教程
  8. TeeChart 2022.2 for .NET
  9. Android 系统汉字转拼音 HanziToPinyin
  10. Visio画图删去四周白边
  11. arcgis注册数据源_将表注册到地理数据库
  12. cruzer php sandisk 闪迪u盘量产工具_sandisk量产工具(闪迪U盘量产工具) 1.4
  13. android 7.0低电耗Doze模式
  14. 智课雅思词汇---十八、前缀peri是什么意思
  15. Roaring Bitmap 更好的位图压缩算法
  16. 二逼青年暑假深圳面试记
  17. java图片叠加_[原创]JAVA中图片上叠加文字的方法
  18. 避暑山庄消失的三十六景,曾经那么美!
  19. js几行代码搞定html转图片制作海报,html2canvas应用实例
  20. go-micro教程 — 第二章 go-micro v3 使用Gin、Etcd

热门文章

  1. tomcat原理及调优
  2. 浪潮之巅读书笔记(三)
  3. wikisql 数据集解释_【Wikidata】维基数据详解
  4. windows有哪些版本
  5. 2022年数维杯国际赛ABCD题思路
  6. JDK8_新特性_详细总结+代码(1)Lambda表达式
  7. 多目标优化系列(一)NSGA-Ⅱ
  8. 【Python自然语言处理】读书笔记:第一章:语言处理与Python
  9. 网上订餐系统设计与实现(JSP+SSM+MySQL)
  10. R语言ggplot2可视化:使用patchwork包的plot_layout函数将多个可视化图像组合起来,ncol参数指定行的个数、byrow参数指定按照行顺序排布图