BestCoder Round #3 小记


1001


1002

 直接2次扫描

const  int  maxn  = 40008  ;

int   cnt[maxn]  , negcnt[maxn] ;
int   x[maxn] ;


int main(){
    int t  , sum ,  n ,  m  , i , j , c , k  , a , b  , s ;
    while(cin>>n>>m){
          for(i = 1 ; i <= n ; i++){
              scanf("%d" , &x[i]) ;
              if(x[i] == m)  k = i ;
          }
          s = 0 ;
          memset(cnt , 0 , sizeof(cnt)) ;
          memset(negcnt , 0 , sizeof(negcnt)) ;

          for(i = 1 ; i <= n ; i++){
              if(x[i] < m)  s-- ;
              else if(x[i] > m)   s++ ;

              if(i >= k){
                   if(s >= 0)  cnt[s]++ ;
                   else        negcnt[-s]++ ;
              }
          }

          int  g = 0  ;
          sum = 0 ;
          for(i = 1 ; i <= k ; i++){
                if(g < 0)  sum += negcnt[-g] ;
                else       sum += cnt[g] ;
                if(x[i] < m)  g-- ;
                else          g++ ;
          }

          cout<< sum << endl ;

    }
    return 0;
}



1003

题目大意:给定一个字符串,由小写字母组成,最多包含一个问号,问号可以表示空或者任意一个字母。问有多少个子串,字母出现的次数均为偶数。

hash

同奇同偶 性质

以‘?’分割,分成左右集合。 枚举[‘a’ , 'z']构成左边集合,枚举右集合相等的情况。

‘?’可以为尾巴, 那么只需将‘?’处的hash值,变为‘?’左邻处的hash值 。

起点为首字符,将0处的hash值放入左集合

const  int  maxn =  20008 ;
char   str[maxn]   ;
int   to[maxn]  ;

map<int , int>  mall , mleft , mright  ;

int   main(){
      to[0] = 0 ;
      int i , j , t , n  ,  pos  , sum  , c , d  ;
      cin>>t ;
      while(t--){
           scanf("%s" , str+1) ;
           n = strlen(str + 1) ;
           pos = -1 ;
           for(i = 1 ; i <= n ; i++){
                if(str[i] == '?'){
                      to[i] = to[i-1] ;
                      pos = i ;
                }
                else   to[i] = to[i-1] ^ (1 << (str[i] - 'a')) ;
           }
           mall.clear() , mleft.clear() , mright.clear() ;
           for(i = 0 ; i <= n ; i++){
               mall[to[i]]++ ;
               if(pos != -1 && i < pos)  mleft[to[i]]++ ;
               else if(pos != -1 && i >= pos) mright[to[i]]++ ;// be calful >=
           }
           sum = 0 ;
           if(pos != -1){
               for(map<int,int>::iterator it = mleft.begin() ; it != mleft.end() ; it++){
                    c =  it->first ;
                    for(i = 0 ; i < 26 ; i++){
                        d = c ^ (1 << i) ;
                        map<int , int>::iterator oit = mright.find(d) ;
                        if(oit != mright.end())  sum += (it->second) * (oit->second) ;
                    }
               }
           }
           for(map<int , int>::iterator it = mall.begin() ; it != mall.end() ; it++)
               sum +=  (it->second) * (it->second - 1) / 2 ;

           printf("%d\n" , sum) ;
      }
      return 0 ;
}








你可能感兴趣的:(BestCoder Round #3 小记)