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
原文地址:https://www.cnblogs.com/Opaser/p/4802774.html