zoukankan      html  css  js  c++  java
  • bzoj2011: [Ceoi2010]Mp3 Player

    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:

    第一种:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 char ch;
     8 bool ok;
     9 void read(int &x){
    10     ok=0;
    11     for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    12     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    13     if (ok) x=-x;
    14 }
    15 const int maxn=100005;
    16 const int inf=0x7f7f7f7f;
    17 char s[2];
    18 int n,vm,v[maxn];
    19 struct oper{
    20     int id,t;
    21 }op[maxn];
    22 bool cmp(const oper &a,const oper &b){return a.t>b.t;}
    23 void write(int a,int b){
    24     if (a==inf) puts("infinity");
    25     else printf("%d %d
    ",a,b);    
    26 }
    27 struct Node{
    28     int sum,maxv,minv;
    29 };
    30 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)};}
    31 struct Seg{
    32     Node node[maxn<<2],res,tmp;
    33     void build(int k,int l,int r){
    34         if (l==r){node[k]=(Node){v[l],v[l],v[l]};return;}
    35         int m=(l+r)>>1;
    36         build(k<<1,l,m),build((k<<1)+1,m+1,r),node[k]=node[k<<1]+node[(k<<1)+1];
    37     }
    38     void modify(int k,int l,int r,int x){
    39         if (l==r){node[k]=(Node){0,0,inf};return;}
    40         int m=(l+r)>>1;
    41         if (x<=m) modify(k<<1,l,m,x); else modify((k<<1)+1,m+1,r,x);
    42         node[k]=node[k<<1]+node[(k<<1)+1];
    43     }
    44     int query_max(int k,int l,int r){
    45         if (l==r){tmp=res+node[k];return tmp.maxv<vm;}
    46         int m=(l+r)>>1;
    47         tmp=res+node[k<<1];
    48         if (tmp.maxv>=vm) return query_max(k<<1,l,m);
    49         res=tmp; return query_max((k<<1)+1,m+1,r)+(m-l+1);
    50     }
    51     int query_min(int k,int l,int r){
    52         if (l==r){tmp=res+node[k];return tmp.minv>0;}
    53         int m=(l+r)>>1;
    54         tmp=res+node[k<<1];
    55         if (tmp.minv<=0) return query_min(k<<1,l,m);
    56         res=tmp; return query_min((k<<1)+1,m+1,r)+(m-l+1);
    57     }
    58     Node query(int k,int l,int r,int x){
    59         if (l==r) return node[k];
    60         int m=(l+r)>>1;
    61         if (x<=m) return query(k<<1,l,m,x);
    62         else return node[k<<1]+query((k<<1)+1,m+1,r,x);
    63     }
    64     bool check(int ans){
    65         int t1,t2;
    66         res=(Node){0,0,inf},t1=query_max(1,0,n-1);
    67         res=(Node){0,0,inf},t2=query_min(1,0,n-1);
    68         if (t1==n&&t2==n){write(ans,node[1].sum);return true;}
    69         if (t1>t2){
    70             res=query(1,0,n-1,t1);
    71             if (res.minv<0) return false;
    72             if (t1==n) write(ans,node[1].sum);
    73             else write(ans,vm);
    74             return true;
    75         }
    76         else{
    77             res=query(1,0,n-1,t2);
    78             if (res.maxv>vm) return false;
    79             write(ans,vm);
    80             return true;
    81         }
    82         return false;
    83     }
    84 }T;
    85 int main(){
    86     read(n),read(vm),read(v[0]);
    87     for (int i=n;i>=1;i--) scanf("%s",s),v[i]=s[0]=='+'?-1:1,read(op[i].t),op[i].id=i;
    88     T.build(1,0,n-1);
    89     if (T.check(inf)) return 0;
    90     for (int i=1;i<n;i++) op[i].t-=op[i+1].t;
    91     sort(op+1,op+n,cmp);
    92     for (int i=1,j;i<n;i=j){
    93         for (j=i;op[j].t==op[i].t;j++) T.modify(1,0,n-1,op[j].id);
    94         if (T.check(op[i].t-1)) return 0;
    95     }
    96     return 0;
    97 }

    第二种:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 char ch;
     8 bool ok;
     9 void read(int &x){
    10     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    11     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    12     if (ok) x=-x;
    13 }
    14 const int maxn=100005;
    15 inline int min(const int &a,const int &b){
    16     int diff=b-a;
    17     return a+(diff&(diff>>31));
    18 }
    19 inline int max(const int &a,const int &b){
    20     int diff=b-a;
    21     return b-(diff&(diff>>31));
    22 }
    23 char s[2];
    24 int n,vm,v2;
    25 struct Oper{
    26     int op,t,id;
    27 }oper[maxn];
    28 bool cmp(const Oper &a,const Oper &b){return a.t>b.t||(a.t==b.t&&a.id<b.id);}
    29 struct Data{
    30     int a,b,c;
    31     void init(){a=0,b=vm,c=0;}
    32 }res;
    33 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};}
    34 struct Seg{
    35     #define ls k<<1
    36     #define rs (k<<1)+1
    37     Data val[maxn<<2];
    38     void build(int k,int l,int r){
    39         if (l==r){val[k]=(Data){0,vm,oper[l].op};return;}
    40         int m=(l+r)>>1;
    41         build(ls,l,m),build(rs,m+1,r),val[k]=val[ls]+val[rs];
    42     }
    43     void modify(int k,int l,int r,int x){
    44         if (l==r){val[k].init();return;}
    45         int m=(l+r)>>1;
    46         if (x<=m) modify(ls,l,m,x); else modify(rs,m+1,r,x);
    47         val[k]=val[ls]+val[rs];
    48     }
    49     void modify(int x,int op){modify(1,2,n,x);}
    50 }T;
    51 int calc(){
    52     if (v2==res.b&&res.b-res.c<=vm) return vm;
    53     return max(0,min(v2-res.c,vm));
    54 }
    55 int f(int x){return min(res.b,max(res.a,x+res.c));}
    56 int main(){
    57     read(n),read(vm),read(v2);
    58     for (int i=1;i<=n;i++) scanf("%s",s),read(oper[i].t),oper[i].op=s[0]=='+'?1:-1,oper[i].id=i;
    59     T.build(1,2,n);
    60     for (int i=n;i>=1;i--) oper[i].t-=oper[i-1].t;
    61     sort(oper+2,oper+n+1,cmp);
    62     res=T.val[1];
    63     if (f(0)<=v2&&v2<=f(vm)){puts("infinity");return 0;}
    64     for (int i=2,j;i<=n;i=j){
    65         for (j=i;oper[j].t==oper[i].t;j++) T.modify(oper[j].id,oper[j].op);
    66         res=T.val[1];
    67         if (f(0)<=v2&&v2<=f(vm)){printf("%d %d
    ",oper[i].t-1,calc());return 0;}
    68     }
    69     return 0;
    70 }
  • 相关阅读:
    远程控制.scrcpy&其他资料&我的游戏辅助方案
    虚拟机.第三方.droid4x(海马玩)
    私.微信
    私.Modbus测试_ZC03_rtu,ascii,tcp
    Modbus资料
    私.Modbus测试_ZC02_串口方式
    私.Modbus测试_ZC01_TCP方式
    私.01.serialport
    C# Type Basics
    NORFLASH驱动详细说明
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/5421691.html
Copyright © 2011-2022 走看看