Codeforce 1420 B. Rock and Lever 解析(思維)

今天我們來看看CF1420B
題目連結

題目
給一個數列(a),求有多少種((i,j))使得(i<j)(a_i&a_jge a_ioplus a_j)

前言



想法

觀察到,由於(1&1=1)(1oplus1=0),所以(a_i&a_j)有的(bit)(a_ioplus a_j)都不會有。
而繼續觀察到,如果(a_i,a_j)最左邊的(bit)是一樣的(例如都是第(10)(bit)),那麼(a_i&a_jge a_ioplus a_j)。而如果不一樣,那麼(a_i,a_j)中擁有最左邊的(bit)的那個數字,會造成(a_i&a_j<a_ioplus a_j)(因為(2^i>sumlimits_{j=0}^{i-1}2^j))。

所以只需要從數列左邊看到右邊,每次對於元素(a[i]),看看前面有多少元素的最左(bit)(a[i])一樣即可。

程式碼:

const int _n=1e5+10;
int t,tt,n,a[_n],cnt[40];
main(void) {ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
  cin>>t;while(t--){
    memset(cnt,0,sizeof cnt);
    cin>>n;rep(i,0,n)cin>>a[i];
    ll ans=0;rep(i,0,n){
      tt=32-__builtin_clz(a[i]);
      ans+=cnt[tt];
      cnt[tt]++;
    }cout<<ans<<'n';
  }
  return 0;
}

標頭、模板請點Submission看
Submission

内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/petjelinux/p/13727622.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!