0w1

Bangladesh OI 2016 National Round pF. Batman and Robin ( Ad hoc )

http://codeforces.com/gym/101212/attachments/download/5014/bangladesh-informatics-olympiad-2016-en.pdf
Dashboard - Bangladesh Informatics Olympiad 2016 - Codeforces

題意:
給你 L, A,代表字串的大小,以及可能字符集合大小。
接著給字串,以數字表示字符異同關係。
現在有人跟你說,他心裡想的字串消去某個字符後,恰好和你的字串裡消去某個字符後是一樣的。
求這個人心裡可能想的字串方案數,對 1e9 + 7 取模。

資料規模:
1 ≤ T ≤ 5
For easy version: 1 ≤ L ≤ 20 (easy), 1 ≤ A ≤ 26
For hard version: 1 ≤ L ≤ 60 (hard), 1 A ≤ 1e9
TL: 4000 ms
ML: 256 MB

解法:
換句話說,要不重複的算有多少種 W' 是 W 插入一個新的字後,刪除一個字得到的。
分兩種情況討論,將加入的是有在 W 裡面的元素,或非。
如果是不在 W 裡的元素,暴力算一次,然後乘上這樣的元素數量,加在答案上。
如果是,那麼也最多 L ^ 2 種,所以輕鬆暴力做。
暴力做法是枚舉要加入的元素、加入的位子、刪除的元素,用 vector 亂搞,然後用 set 維護。

時間 / 空間複雜度:
O( L ^ 3 lg L )

閒話:
一開始沒仔細看有 4000 ms,我還真瞎寫了噁爛 hash。

void solve(){
  int T; cin >> T;
  for( int kase = 1; kase <= T; ++kase ){
    int L, A; cin >> L >> A;
    vi W( L );
    for( int i = 0; i < L; ++i ){
      cin >> W[ i ];
    }
    set< int > exist;
    for( int i = 0; i < L; ++i ){
      exist.emplace( W[ i ] );
    }
    int ans = 0;
    set< vi > dict;
    for( int del = 0, add = ( int ) 1e9 + 1; del < L; ++del ){
      vi t;
      for( int i = 0; i < L; ++i ){
        if( i == del ) continue;
        t.emplace_back( W[ i ] );
      }
      for( int pos = 0; pos < L; ++pos ){
        vi f;
        for( int i = 0; i < L; ++i ){
          if( i == pos ){
            f.emplace_back( add );
          } else{
            f.emplace_back( t[ i > pos ? i - 1 : i ] );
          }
        }
        dict.emplace( f );
      }
    }
    ans = 1LL * dict.size() * ( A - exist.size() ) % MOD7;
    dict.clear();
    dict.emplace( W );
    for( int add : exist ){
      for( int del = 0; del < L; ++del ){
        vi t;
        for( int i = 0; i < L; ++i ){
          if( i == del ) continue;
          t.emplace_back( W[ i ] );
        }
        for( int pos = 0; pos < L; ++pos ){
          vi f;
          for( int i = 0; i < L; ++i ){
            if( i == pos ){
              f.emplace_back( add );
            } else{
              f.emplace_back( t[ i > pos ? i - 1 : i ] );
            }
          }
          dict.emplace( f );
        }
      }
    }   
    ( ans += dict.size() ) %= MOD7;
    cout << ans << endl;
  }
}