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. maven项目文件乱码问题

    今日碰到maven项目中的一个资源文件出现乱码,排查发现是在.setting文件夹下的org.eclipse.core.resources.prefs文件导致的. 修改前的编码规则如下: <sp ...

  2. mysql 配置参数

    mysql JDBC Driver 常用的有两个,一个是gjt(Giant Java Tree)组织提供的mysql驱动,其JDBC Driver名称(JAVA类名)为:org.gjt.mm.mysq ...

  3. Spring XD 1.1 M2 and 1.0.3 released---support kafka

    官方地址:http://spring.io/blog/2014/12/23/spring-xd-1-1-m2-and-1-0-3-released On behalf of the Spring XD ...

  4. (转载)为啥我们要学习Linux

    学习Linux也有一阵子了,这过程中磕磕撞撞的,遇到了问题,也解决了一些问题,学习的路子是曲折的,想总结点啥的,让刚刚学习Linux的不会望而生畏. 为啥我们要学习Linux 技术的价值不在于这个技术 ...

  5. Java基础知识强化之IO流笔记28:BufferedOutputStream / BufferedInputStream(字节缓冲区流) 之BufferedOutputStream写出数据

    1. BufferedOutputStream / BufferedInputStream(字节缓冲区流)的概述 通过定义数组的方式确实比以前一次读取一个字节的方式快很多,所以,看来有一个缓冲区还是非 ...

  6. C语言 打印圣诞树

    再回首<C语言编程基础>,其中不少当年老师出的题,做完后稍微做了下修改,可以输入任意行数来打印圣诞树,行数越大,树越大,当然显示器也要越大,不然就折行了. 纯粹练手跟加强记忆的东西,做个记 ...

  7. Linux Apache SVN

    yum install mod_dav_svn subversion  httpd mkdir /var/www/svnsvnadmin create /var/www/svn/puppetcd /v ...

  8. linux根下目录详解及分区建议

    / 根目录    分区大小一定要充足,一般不小于5GB/bin,/usr/bin 普通用户使用命令    建议和/放一起/sbin,/usr/sbin 管理员使用命令/bin,/sbin 操作系统自身 ...

  9. 15第十五章UDF用户自定义函数(转载)

    15第十五章UDF用户自定义函数 待补上 原文链接 本文由豆约翰博客备份专家远程一键发布

  10. CoreAnimation1-图层树、寄宿图以及图层几何学

    (一)图层的树状结构 Core Animation其实是一个令人误解的命名.你可能认为它只是用来做动画的,但实际上它是从一个叫做Layer Kit这么一个不怎么和动画有关的名字演变而来,所以做动画这只 ...