Description

Georg有个MP3 Player,没有任何操作T秒钟就会锁定,这时按下任意一个键就会变回没锁定的状态,但不会改变频道。只有在没锁定的状态下按键才有可能改变频道。 MP3的频道为0~Vmax(2<=Vmax<=5000),如果现在是X频道,若X<>Vmax,在无锁状态下按+,X就会加1。若X<>0,在无锁状态下按-,X就会减一。 想在Georg忘记了MP3的T是多少。他想通过一段操作试验一下。然后他就写下他的操作顺序和最后停留的频道V2(0<=V2<=Vmax),然后就给你了,你要求的是T的最大值和T在这个值的情况下,第一个操作前的频道V1的最大可能数。若T为无限大时经过这段操作最后能停在V2,则输出infinity。

Input

第1行:N,Vmax,V2 N表示Georg操作了N次(2<=N<=100000); 以下N行,每行第一个为字符C(C为'+'或'-'),第二个为数字Ti(0<=Ti<=10^9), 表示Georg在Ti秒按下了C键。

Output

如题所述。

Sample Input

6 4 3
- 0
+ 8
+ 9
+ 13
- 19
- 24

Sample Output

5 4

题解:

这题肯定要从大到小枚举T,判断这时有效的操作能否有解

判断能否有解有两种做法

第一种是将所有操作倒过来作,这样加边减,减变加

无解的情况就是 在未到达过0之前,最后某段音量>vmax 或未到达过vmax之前,最后某段音量<0

然后就是分情况讨论了

如果没有到过vmax,那么最大初始音量为所有操作之和

否则就是vmax

第二种就是类似清华集训V那题一样的去维护一个分段函数f(x)

其定义域为[0,vmax],表示这段操作的初始音量,值域也为[0,vmax],表示这段操作后的音量为多少

然后也是一通讨论

code:

第一种:

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
char ch;
bool ok;
void read(int &x){
ok=;
for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=;
for (x=;isdigit(ch);x=x*+ch-'',ch=getchar());
if (ok) x=-x;
}
const int maxn=;
const int inf=0x7f7f7f7f;
char s[];
int n,vm,v[maxn];
struct oper{
int id,t;
}op[maxn];
bool cmp(const oper &a,const oper &b){return a.t>b.t;}
void write(int a,int b){
if (a==inf) puts("infinity");
else printf("%d %d\n",a,b);
}
struct Node{
int sum,maxv,minv;
};
Node operator+(const Node &a,const Node &b){return (Node){a.sum+b.sum,max(a.maxv,a.sum+b.maxv),min(a.minv,a.sum+b.minv)};}
struct Seg{
Node node[maxn<<],res,tmp;
void build(int k,int l,int r){
if (l==r){node[k]=(Node){v[l],v[l],v[l]};return;}
int m=(l+r)>>;
build(k<<,l,m),build((k<<)+,m+,r),node[k]=node[k<<]+node[(k<<)+];
}
void modify(int k,int l,int r,int x){
if (l==r){node[k]=(Node){,,inf};return;}
int m=(l+r)>>;
if (x<=m) modify(k<<,l,m,x); else modify((k<<)+,m+,r,x);
node[k]=node[k<<]+node[(k<<)+];
}
int query_max(int k,int l,int r){
if (l==r){tmp=res+node[k];return tmp.maxv<vm;}
int m=(l+r)>>;
tmp=res+node[k<<];
if (tmp.maxv>=vm) return query_max(k<<,l,m);
res=tmp; return query_max((k<<)+,m+,r)+(m-l+);
}
int query_min(int k,int l,int r){
if (l==r){tmp=res+node[k];return tmp.minv>;}
int m=(l+r)>>;
tmp=res+node[k<<];
if (tmp.minv<=) return query_min(k<<,l,m);
res=tmp; return query_min((k<<)+,m+,r)+(m-l+);
}
Node query(int k,int l,int r,int x){
if (l==r) return node[k];
int m=(l+r)>>;
if (x<=m) return query(k<<,l,m,x);
else return node[k<<]+query((k<<)+,m+,r,x);
}
bool check(int ans){
int t1,t2;
res=(Node){,,inf},t1=query_max(,,n-);
res=(Node){,,inf},t2=query_min(,,n-);
if (t1==n&&t2==n){write(ans,node[].sum);return true;}
if (t1>t2){
res=query(,,n-,t1);
if (res.minv<) return false;
if (t1==n) write(ans,node[].sum);
else write(ans,vm);
return true;
}
else{
res=query(,,n-,t2);
if (res.maxv>vm) return false;
write(ans,vm);
return true;
}
return false;
}
}T;
int main(){
read(n),read(vm),read(v[]);
for (int i=n;i>=;i--) scanf("%s",s),v[i]=s[]=='+'?-:,read(op[i].t),op[i].id=i;
T.build(,,n-);
if (T.check(inf)) return ;
for (int i=;i<n;i++) op[i].t-=op[i+].t;
sort(op+,op+n,cmp);
for (int i=,j;i<n;i=j){
for (j=i;op[j].t==op[i].t;j++) T.modify(,,n-,op[j].id);
if (T.check(op[i].t-)) return ;
}
return ;
}

第二种:

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
char ch;
bool ok;
void read(int &x){
for (ok=,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=;
for (x=;isdigit(ch);x=x*+ch-'',ch=getchar());
if (ok) x=-x;
}
const int maxn=;
inline int min(const int &a,const int &b){
int diff=b-a;
return a+(diff&(diff>>));
}
inline int max(const int &a,const int &b){
int diff=b-a;
return b-(diff&(diff>>));
}
char s[];
int n,vm,v2;
struct Oper{
int op,t,id;
}oper[maxn];
bool cmp(const Oper &a,const Oper &b){return a.t>b.t||(a.t==b.t&&a.id<b.id);}
struct Data{
int a,b,c;
void init(){a=,b=vm,c=;}
}res;
Data operator+(const Data &x,const Data &y){return (Data){min(y.b,max(y.a,x.a+y.c)),max(y.a,min(y.b,x.b+y.c)),x.c+y.c};}
struct Seg{
#define ls k<<1
#define rs (k<<1)+1
Data val[maxn<<];
void build(int k,int l,int r){
if (l==r){val[k]=(Data){,vm,oper[l].op};return;}
int m=(l+r)>>;
build(ls,l,m),build(rs,m+,r),val[k]=val[ls]+val[rs];
}
void modify(int k,int l,int r,int x){
if (l==r){val[k].init();return;}
int m=(l+r)>>;
if (x<=m) modify(ls,l,m,x); else modify(rs,m+,r,x);
val[k]=val[ls]+val[rs];
}
void modify(int x,int op){modify(,,n,x);}
}T;
int calc(){
if (v2==res.b&&res.b-res.c<=vm) return vm;
return max(,min(v2-res.c,vm));
}
int f(int x){return min(res.b,max(res.a,x+res.c));}
int main(){
read(n),read(vm),read(v2);
for (int i=;i<=n;i++) scanf("%s",s),read(oper[i].t),oper[i].op=s[]=='+'?:-,oper[i].id=i;
T.build(,,n);
for (int i=n;i>=;i--) oper[i].t-=oper[i-].t;
sort(oper+,oper+n+,cmp);
res=T.val[];
if (f()<=v2&&v2<=f(vm)){puts("infinity");return ;}
for (int i=,j;i<=n;i=j){
for (j=i;oper[j].t==oper[i].t;j++) T.modify(oper[j].id,oper[j].op);
res=T.val[];
if (f()<=v2&&v2<=f(vm)){printf("%d %d\n",oper[i].t-,calc());return ;}
}
return ;
}

bzoj2011: [Ceoi2010]Mp3 Player的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. android服务之MP3播放(2)

    该播放器将会直接从网络上获取资源进行播放,并提供进度条显示的功能 布局文件 布局文件中使用Seekbar组件来显示进度条 <?xml version="1.0" encodi ...

  3. android之MP3播放器(1)

    该播放器只是对本地的MP3文件进行简单的播放 布局文件 布局文件中设置了三个按钮分别来进行播放.暂停和继续播放 <?xml version="1.0" encoding=&q ...

  4. 你也可以用java的swing可以做出这么炫的mp3播放器_源码下载

    I had published the blog : 你用java的swing可以做出这么炫的mp3播放器吗? and to display some screenshots about this M ...

  5. 20 Free Open Source Web Media Player Apps

    free Media Players (Free MP3, Video, and Music Player ...) are cool because they let web developers ...

  6. 视频播放flv player的使用

    JW FLV PLAYER 中文文档 使用方法:如果你仅需要播放一个FLV文件[例如“video.flv”],那么只要把“video.flv”和压缩包内的 flvplayer.swf复制到同一个目录内 ...

  7. 关于jmf不能播放mp3的问题解决

    想写个JAVA的MP3音乐管理器,使用JMF插件,但发现运行时总报一个异常: Unable to handle format: mpeglayer3, 44100.0 Hz, 16-bit, Ster ...

  8. 华为上机测试题(MP3光标移动-java)

    PS:此题满分,可参考 描述: MP3 Player因为屏幕较小,显示歌曲列表的时候每屏只能显示几首歌曲,用户要通过上下键才能浏览所有的歌曲.为了简化处理,假设每屏只能显示4首歌曲,光标初始的位置为第 ...

  9. 20款 JavaScript 开发框架推荐给前端开发者

    下面,我们给大家提供了一个用于 HTML5 开发的各种用途的 JavaScript 库列表.这些框架能够给前端开发人员提供更好的功能实现的解决方案.如果你有收藏优秀的框架,也可以在后面的评论中分享给我 ...

随机推荐

  1. Thoughtworks的技术雷达

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:Thoughtworks的技术雷达.

  2. linux 通用时钟框架CCF

    linux CCF 时钟框架 简单介绍 这里讲的时钟是给soc各组件提供时钟的树状框架,并非内核使用的时间,和其它模块一样,clk也有框架,用以适配不同的平台.适配层之上是客户代码和接口,也就是各模块 ...

  3. Android开发_后台任务task管理_allowTaskReparenting alwaysRetainTaskState clearTaskOn

    1.android:allowTaskReparenting 这个属性用来标记一个Activity实例在当前应用退居后台后,是否能从启动它的那个task移动到有共同affinity的task,“tru ...

  4. linux IO 内核参数调优 之 原理和参数介绍

    1.  page cache linux操作系统默认情况下写都是有写缓存的,可以使用direct IO方式绕过操作系统的写缓存.当你写一串数据时,系统会开辟一块内存区域缓存这些数据,这块区域就是我们常 ...

  5. C++使用Json作为数据包装格式的通信

    出处:http://adebugger.cn/2009/11/cpp-json-data-communication/ http://hi.baidu.com/tibelf/item/6be2accd ...

  6. ubuntu权限管理常用命令 分类: linux ubuntu 学习笔记 2015-07-05 14:15 77人阅读 评论(0) 收藏

    1.chmod 第一种方式 chomd [{ugoa}{+-=}{rwx}] [文件或者目录] u 代表该文件所属用户 g 代表该文件所属用户组 o 代表访客 a 代表所有用户 +-=分别表示增加权限 ...

  7. GitHub详细教程

    GitHub详细教程 Table of Contents 1 Git详细教程 1.1 Git简介 1.1.1 Git是何方神圣? 1.1.2 重要的术语 1.1.3 索引 1.2 Git安装 1.3 ...

  8. 用php切割大图片为成规则的小图

    将根据xml配置,将合并后的大图切割成一系列小图 <?php /** * 将大图片按照配置切割成一定比例的小图片 * 并按照一定规则给小图片命名 * * 使用方法: *根据guardians/g ...

  9. C# QRCode、DataMatrix和其他条形码的生成和解码软件

    今天制造了一个C#的软件,具体是用于生成二维码和条形码的,包括常用的QRCode.DataMatrix.Code128.EAN-8等等. 使用的第三方类库是Zxing.net和DataMatrix.n ...

  10. 构建可克隆的对象(ICloneable)

    ICloneable接口 如果想使自己的自定义类型支持向调用方返回自身同样副本的能力,需要实现标准ICloneable接口. namespace System { // // 摘要: // Suppo ...