• Codeforces Round #312 (Div. 2)


    A

    #include <iostream>
    #include<algorithm>
    #include <string.h>
    #include <cstdio>
    #include <vector>
    using namespace std;
    struct point
    {
        int x,p;
        bool operator < (const point &rhs)const {
          return x<rhs.x;
        }
    }P[105];
    
    int main()
    {
        int n;
        while(scanf("%d",&n)==1)
        {
            for(int i=0; i<n;i++)
                {
                     scanf("%d%d",&P[i].x,&P[i].p);
                }
            sort(P,P+n);
            int loc=-1;
            for(int i=0; i<n; i++)
            if(P[i].x>0){
                loc=i;break;
            }
            if(loc==-1){
                printf("%d
    ",P[n-1].p);continue;
            }
            if(loc==0){
                printf("%d
    ",P[0].p);continue;
            }
            long long ans=0;
            int L=0;
            while(true)
            {
                if(loc+L>=n||loc-L-1<0){
                    if(loc+L>=n){
                        ans+=P[loc-L-1].p;
                    }else ans+=P[loc+L].p;
                    break;
                }
               ans+=P[loc+L].p+P[loc-L-1].p;
               L++;
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    View Code

    B

    #include <iostream>
    #include<algorithm>
    #include <string.h>
    #include <cstdio>
    #include <vector>
    using namespace std;
    const int maxn=1000006;
    int num[maxn];
    int L[maxn],R[maxn];
    int main()
    {
        int n;
        while(scanf("%d",&n)==1)
        {
            memset(num,0,sizeof(num));
            for(int i=1; i<=n;i++){
                int a;
                scanf("%d",&a);
                if(num[a]==0){
                    L[a]=i;R[a]=i;
                }else {
                   R[a]=i;
                }
                num[a]++;
            }
                int id=0;
                for(int i=0; i<=1000000; i++)
                     if(num[i]>num[id])id=i;
                int cL=L[id],cR=R[id];
                for(int i=0; i<=1000000; i++)
                     if(num[i]==num[id]&&R[i]-L[i]<R[id]-L[id]) id=i;
                printf("%d %d
    ",L[id],R[id]);
    
        }
        return 0;
    }
    View Code

    C

    首先将第一个点能到的数值计算出来 我们要知道 最后相等的时候肯定是第一个点他要能够达到,那么最多就10多种可能,然后接着除了下降的值外,要翻倍的值就如果在1中没有出现那么就不要他了因为那个值 第一个试管的体积到不到,然后bfs 找状态就好了

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <string.h>
    #include <set>
    #include <queue>
    using namespace std;
    const int maxn=100005;
    int a[maxn+10],num[maxn+10];
    struct point{
       int x,stp;
       point(int a=0,int b=0){
          x=a; stp=b;
       }
    };
    bool use[maxn*2];
    int mark[maxn*2];
    void solve(int d,int id)
    {
         queue<point>Q;
            mark[d]=id;
            num[d]++;
            Q.push(point(d,0));
        while(!Q.empty())
            {
                 point t=Q.front();Q.pop();
                if(t.x*2<=maxn&&use[t.x*2])
                    {
                        if(mark[t.x*2]!=id){
                            mark[t.x*2]=id;
                            num[t.x*2]++;
                            a[t.x*2]+=t.stp+1;
                            Q.push(point(t.x*2,t.stp+1));
                        }
                    }
                if(t.x/2>0)
                    {
                        if(mark[t.x/2]!=id){
                              mark[t.x/2]=id;
                            num[t.x/2]++;
                            a[t.x/2]+=t.stp+1;
                            Q.push(point(t.x/2,t.stp+1));
                        }
                    }
            }
    }
    void init(int d)
    {
        queue<int>Q;
            Q.push(d);
            use[d]=true;
        while(!Q.empty())
            {
                 int t=Q.front();Q.pop();
                if(t*2<maxn)
                    {
                        if(use[t*2]==false){
                            use[t*2]=true;
                            Q.push(t*2);
                        }
                    }
                if(t/2>0)
                    {
                        if(use[t/2]==false){
                            use[t/2]=true;
                            Q.push(t/2);
                        }
                    }
            }
    }
    int C[maxn];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            {
                 scanf("%d",&C[i]);
    
            }
            if(n==1){
                printf("0
    ");return 0;
            }
        init(C[0]);
        for(int i=0; i<n; i++)
            {
                solve(C[i],i+1);
            }
        int ans=2147483647;
        for(int i=1; i<maxn;i++)
        if(num[i]==n)
            {
                ans=min(ans,a[i]);
            }
        printf("%d
    ",ans);
        return 0;
    }
    View Code

    D

    我们将每个影响都不断地扩大知道最后一层,然后采用

    线段树 先把赋值为0的操作全做了,然后在做存在操作,如果值为0那么就不要操作了,这样判断是否成功

    #include <iostream>
    #include <algorithm>
    #include <string.h>
    #include <cstdio>
    #include <vector>
    using namespace std;
    const int maxn=100005*6;
    typedef long long LL;
    struct elem
    {
       LL I,L,R;
    
       elem(LL cI=0,LL cL=0,LL cR=0)
       {
            I=cI; L=cL; R=cR;
       }
    }A[100005],B[100005];
    LL C[maxn],ge;
    struct Itree
    {
         LL val[100000*30];
         LL cL,cR,ans,loc;
         void build(int L, int R, int o)
         {
               if(L==R)
                {
                     val[o]=1;return ;
                }
               int mid=(L+R)>>1;
               build(L,mid,o*2);
               build(mid+1,R,o*2+1);
               val[o]=val[o*2]+val[o*2+1];
         }
         void update(int L, int R, int o){
             if(cL<=L && R<=cR)
                {
                  val[o]=0;
                   return ;
                }
             if(val[o]==0)return ;
             int mid=(L+R)>>1;
             if(cL<=mid) update(L,mid, o*2);
             if(cR>mid) update(mid+1,R,o*2+1);
             val[o]=val[o*2]+val[o*2+1];
         }
         void query(int L,int R, int o)
         {
                if(L==R){
                    if(val[o]!=0){
                        loc=L; ans+=val[o];
                    }
                    return ;
                }
                int mid=(L+R)>>1;
                if(val[o]==0){
                    val[o*2]=val[o*2+1]=0;
                }
                if(cL<=mid)
                query(L,mid,o*2);
                if(cR>mid)
                query(mid+1,R,o*2+1);
         }
    }T;
     int h,q;
    void add(LL d)
    {
         C[ge++]=d;
         if( ( d + 1 ) <= ( (1LL<<h) - 1) ){
            C[ge++]=d+1;
         }
         if(d-1>=( 1LL<<(h-1) ) ){
            C[ge++]=d-1;
         }
    }
    int main()
    {
    
        int c0=0,c1=0;
        scanf("%d%d",&h,&q);
        for(int i=0; i<q; i++)
            {
                 LL I,L,R,ans;
                 scanf("%I64d%I64d%I64d%I64d",&I,&L,&R,&ans);
                  while( (L*2LL) < (1LL<<h) ){ L=(L*2); }
                  while( (R*2LL+1) < (1LL<<h) ){ R=(R*2)+1; }
                  if(L>R)swap(L,R);
                 if(ans==0){
                    A[c0++]=elem(I,L,R);
                 }else{
                    B[c1++]=elem(I,L,R);
                 }
            }
        LL L=1LL<<(h-1),R=(1LL<<h)-1;
        int cor=0;
        for(int i=0; i<c1; i++)
            {
                  L=max(B[i].L,L);
                  R=min(B[i].R,R);if(L>R){cor=1;break;}
            }
        for(int i=0; i<c1; i++)
            {
                  if( (B[i].L<=L&&B[i].R>=R) ==false ){
                        cor=1; break;
                  }
            }
        if(cor==1){ puts("Game cheated!"); return 0;}
        ge=0;
        C[ge++]=1LL<<(h-1); C[ge++]=(1LL<<h)-1;
        add(L); add(R);
        for(int i=0; i<c0; i++)
            {
                 add(A[i].L); add(A[i].R);
            }
        sort(C,C+ge);
        ge=unique(C,C+ge)-C;
        T.build(1,ge,1);
        for(int i=0; i<c0; i++)
            {
                 T.cL=lower_bound(C,C+ge,A[i].L)-C+1;
                 T.cR=lower_bound(C,C+ge,A[i].R)-C+1;
                 T.update(1,ge,1);
            }
        T.ans=0;
        T.cL=lower_bound(C,C+ge,L)-C+1;
        T.cR=lower_bound(C,C+ge,R)-C+1;
        T.query(1,ge,1);
        if(T.ans==0)
            {
                 puts("Game cheated!");
            }else if(T.ans>1){
                 puts("Data not sufficient!");
            }else {
                printf("%I64d
    ",C[T.loc-1]);
            }
        return 0;
    }
    View Code

    E

    线段树存的是 字母个数,然后我们就直接用字母个数进行类似 基数排序得到答案

    #include <iostream>
    #include <algorithm>
    #include <string.h>
    #include <cstdio>
    using namespace std;
    const int maxn=100005;
    char str[maxn+10];
    struct Itree
    {
         int s[maxn*4];
         int val[maxn*4][26],cL,cR,cK;
         int ch[26];
         void maintain(int o)
         {
             for(int i=0; i<26; i++)
                val[o][i]=val[ o * 2 ][ i ]+val[ o*2 + 1 ][ i ];
         }
         void build(int L, int R, int o)
         {
              memset(val[o],0,sizeof(val[o]));
              s[o]=0;
              if(L==R){
                val[o][str[L-1]-'a' ]++; return ;
              }
              int mid=(L+R)>>1;
              build(L,mid,o*2);
              build(mid+1,R,o*2+1);
              maintain(o);
         }
         void nondecreasing(int L,int R, int o)
         {
             int mid=(R+L)>>1;
             int cur=mid-L+1,nu=0;
             for(int i=0; i<26; i++)
             {
                 if( val[ o ][ i ] + nu <= cur ){
                     val[ o*2 ][ i ] = val[ o ][ i ];
                     nu += val[ o ][ i ];
                     val[ o ][ i ] = 0;
                 }else{
                     val[ o * 2 ][ i ]=cur-nu;
                     val[o][i]-=(cur-nu);
                     nu=cur;
                 }
                 if(nu==cur)break;
             }
             for(int i=0; i<26; i++) {
                    val[o*2+1][i]=val[o][i];
                    val[o][i]=0;
             }
         }
         void  nonincreasing(int L, int R, int o)
         {
             int mid=(R+L)>>1;
             int cur=mid-L+1,nu=0;
             for(int i=25; i>=0; i--)
             {
                 if( val[ o ][ i ] + nu <= cur ){
                     val[ o*2 ][ i ] = val[ o ][ i ];
                     nu += val[ o ][ i ];
                     val[ o ][ i ] = 0;
                 }else
                 {
                     val[ o * 2 ][ i ]=cur-nu;
                     val[o][i]-=(cur-nu);
                     nu=cur;
                 }
                 if(nu==cur)break;
             }
             for(int i=25; i>=0; i--) {
                    val[o*2+1][i]=val[o][i];
                    val[o][i]=0;
             }
    
         }
         void downmatain(int L, int R,int o)
         {
    
             memset(val[o*2],0,sizeof(val[o*2]));
             memset(val[o*2+1],0,sizeof(val[o*2+1]));
             s[o*2+1]=s[o*2]=s[o];
             if(s[o]==1){
                nonincreasing(L,R,o);
             }else if(s[o]==2){
                nondecreasing(L,R,o);
             }
             s[o]=0;
         }
         void query(int L, int R, int o)
         {
              if(cL<=L&&R<=cR)
                {
                     for(int i=0; i<26; i++)
                     ch[i]+=val[o][i];
                    return ;
                }
                if(s[o]!=0)
                downmatain(L,R,o);
                int mid=(L+R)>>1;
               if(cL<=mid)
                    query(L,mid,o*2);
               if(cR>mid)
                    query(mid+1,R,o*2+1);
                maintain(o);
         }
         void Knondecreasing(int L,int R, int o)//递增
         {
    
             int cur=R-L+1,nu=0;
             for(int i=0; i<26; i++)
             {
                 if(ch[i]+nu<=cur)
                    {
                         val[o][i]=ch[i]; nu+=ch[i]; ch[i]=0;
                    }else{
                         val[o][i]=cur-nu;
                         ch[i]-=(cur-nu);
                         nu=cur;
                    }
                    if(nu==cur)break;
             }
         }
         void Knonincreasing(int L, int R, int o)//递减
         {
             int cur=R-L+1,nu=0;
             for(int i=25; i>=0; i--)
                {
    
                    if(ch[i]+nu<=cur){
                        val[o][i]=ch[i]; nu+=ch[i]; ch[i]=0;
                    }else{
                        val[o][i]=cur-nu;
                        ch[i]-=(cur-nu);
                        nu=cur;
                    }
                }
         }
         void update(int L, int R, int o)
         {
              if(cL<=L && R<=cR)
                {
                   s[o]=cK;
                   memset(val[o],0,sizeof(val[o]));
                   if(cK==1) Knonincreasing(L,R,o);
                    else Knondecreasing(L,R,o);
                    return ;
                }
                int mid=(L+R)>>1;
                if(s[o]!=0)
                 {
                     downmatain(L,R,o);
                 }
                if(cL<=mid)update(L,mid,o*2);
                if(cR>mid) update(mid+1,R,o*2+1);
                 maintain(o);
         }
         void print(int L, int R, int o)
         {
              if(L==R){
                  for(int i=0; i<26; i++)
                  if(val[o][i]!=0){
                    printf("%c",'a'+i); return ;
                  }
              }
              if(s[o]!=0)
                downmatain(L,R,o);
              int mid=(L+R)>>1;
              print(L,mid,o*2);
              print(mid+1,R,o*2+1);
            //  maintain(o);
         }
    }T;
    
    int main()
    {
         int n,q;
         scanf("%d%d",&n,&q);
         scanf("%s",str);
         T.build(1,n,1);
         memset(T.ch,0,sizeof(T.ch));
            for(int i=1; i<=q; i++)
            {
                     int L,R,k;
                     scanf("%d%d%d",&L,&R,&k);
                            T.cL=L;T.cR=R;
                            T.cK=k+1;
                            T.query(1,n,1);
                            T.update(1,n,1);
                           // T.print(1,n,1);
            }
            T.print(1,n,1);puts("");
        return 0;
    }
    View Code
  • 相关阅读:
    回溯算法
    cannot import name 'np' in mxnet
    Linux后台运行任务 nohup &
    为Windows Terminal添加右键菜单
    Outlook设置QQ邮箱
    逻辑回归 logistic regression
    Python添加自定义目录到sys.path
    强化学习 策略梯度
    为Windows terminal preview添加右键菜单
    双系统使用Linux引导
  • 原文地址:https://www.cnblogs.com/Opaser/p/4802774.html
Copyright © 2020-2023  润新知