YYHS-怎样更有力气

Posted I__am

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了YYHS-怎样更有力气相关的知识,希望对你有一定的参考价值。

题目描述

OI大师抖儿在夺得银牌之后,顺利保送pku。这一天,抖儿问长者:“我虽然已经保送了,但我的志向是为国家健康工作五十年。请问我应该怎样变得更有力气?”
  长者回答:“你啊,Too Young Too Simple,Sometimes Naive!如果你想要我教你,你要先进行艰苦的修行。”
长者的住宅中有一堵长度为n的墙。每天抖儿起床修行,会选择一段长度为x的区间染成白色。长者的住宅附近有一群香港记者,为了借助抖儿拜访长者,第i天香港记者会将区间[li,ri]染成白色来讨好抖儿(也就是说,每天墙会被抖儿和香港记者各染一次)。现在抖儿已经预先知道了香港记者的动向,他想知道他最少几天就能把墙全部染白,完成修行。

输入

第一行三个整数n,m,x,分别表示墙的长度,天数和区间的长度。
接下来m行,每行两个整数li、ri,表示香港记者在第i天会将区间[li,ri]染成白色。

输出

一行一个整数,表示抖儿最少几天能把墙全部染白。
如果m天之后依然无法染白,则输出“Poor Douer!”

样例输入

10 3 3 2 5 4 8 9 10

样例输出

2

提示

 

【样例说明】

第一天抖儿刷墙的区间为[1,3]

第二天抖儿刷墙的区间为[8,10]

【限制与约定】

测试点编号

n

m

x

1

n≤10

m≤1

 

2

n≤10

m≤10

3

n≤100

m≤100

4

n≤1000

m≤1000

5

n≤10000

m≤10000

6

n≤100000

 

 

m≤100000

 

x=0

7

n≤1018

8

n≤100000

 

9

n≤1018

10

对于所有的数据,保证n≤1018,m≤100000,x≤n且数据随机

【后记】

在你的帮助下,抖儿完成修行的时间是原来的0.01倍。

抖儿对长者说:“我明白了!只有每天坚持锻炼,才能获得力量。”

长者嘿嘿一笑:“你想多了。我只是想让你刷墙而已。”

说完,长者一溜烟地跑了,速度比香港记者还要快好几倍。
 

题解

这道题首先是二分需要的天数

然后你需要统计出哪些区间没有被涂,然后用自己每天能涂的数量判断天数是否可以

但是自己刚开始被如何统计剩余区间给卡住了,后来才知道可以把记者涂的区间从小到大排序(双关键字),然后就是判断剩余区间了

当一段区间是4 5,后面一段是6 7的时候是没有区间漏涂的,所以判断q[i].l-q[i-1].r>1,但其实这样是不对的,自己就是被这个坑了

比如

3 7

4 5

7 8

如果判断q[i].l-q[i-1].r>1,就会以为6~7这段区间是没有被涂得,但是其实前面3 7已经涂到7了,是没有剩余的,所以就要统计之前的max{q[i].r},判断q[i].l-Max>1

统计完剩余区间后是计算自己涂的次数

这里要多判断一下x=0的情况,还有要考虑到x很大的情况,说不定能够涂到两块区间的情况

最后还要注意读入的n是10的18次,要long long读入

技术分享
 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define M 100005
 4 using namespace std;
 5 ll n,m,k,num,ss;
 6 int l,r,mid;
 7 ll x[M],y[M];
 8 bool Flag;
 9 struct node{ ll x,y; }b[M],a[M],q[M];
10 bool cmp(node x,node y){ 
11     if (x.x!=y.x) return x.x<y.x;
12             else return x.y<y.y;
13 }
14 int main(){
15     scanf("%lld%lld%lld",&n,&m,&k);
16     for (int i=1;i<=m;i++)
17         scanf("%lld%lld",&a[i].x,&a[i].y);
18     l=1; r=m;
19     while (l<=r){
20         mid=(l+r)>>1;
21         for (int i=1;i<=mid;i++) b[i]=a[i];
22         sort(b+1,b+1+mid,cmp);
23         int cnt=0;
24         if (b[1].x>1) q[++cnt].x=1,q[cnt].y=b[1].x-1;
25         ll Max=b[1].y;
26         for (int i=2;i<=mid;i++){
27             if (b[i].x-Max>1) q[++cnt].x=Max+1,q[cnt].y=b[i].x-1;
28             if (b[i].y>Max) Max=b[i].y;
29         }
30         if (Max<n) q[++cnt].x=Max+1,q[cnt].y=n;
31         bool flag=false;
32         num=0; int p=1;
33         ll last=0,s;
34         if (!k){
35             if (cnt>0) flag=true;
36         } else
37         while (p<=cnt){
38             if (q[p].x<=last&&q[p].y>last) q[p].x=last+1; else
39             if (q[p].y<=last){
40                 p++; continue;
41             }
42             s=(q[p].y-q[p].x)/k+1;
43             num=num+s;
44             if (num>mid){
45                 flag=true; break;
46             }
47             last=q[p].x+s*k-1;
48             p++;
49         }
50         if (flag) l=mid+1; else{
51             Flag=true;
52             ss=mid;
53             r=mid-1;
54         }
55     }
56     if (!Flag) puts("Poor Douer!"); 
57             else printf("%d\n",ss);
58     return 0;
59 }
View Code

 














































以上是关于YYHS-怎样更有力气的主要内容,如果未能解决你的问题,请参考以下文章

「UR#5」怎样更有力气

NOIP2017练习怎样更有力气(二分答案,线性扫描)

YYHS-手机信号

YYHS-数列

YYHS-论战大原题

YYHS-猜数字(并查集/线段树维护)