ZOJ 3870 Team Formation

2015浙江省赛B题。我用了枚举+二分。。时间复杂度o(64*n),1900ms跑过的。应该有更好的方法。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;

const int maxn = 40;
int base[maxn], tot;
int T, n;
int a[100000 + 10];
int tmp, l, r, mid;
long long ans;

int main()
{
    scanf("%d", &T);
    while (T--)
    {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        sort(a + 1, a + 1 + n);
        ans = 0;
        for (int i = 1; i <= n; i++)
        {
            memset(base, 0, sizeof base);
            tot = 0; tmp = a[i];
            while (tmp) base[tot++] = tmp % 2, tmp = tmp / 2;

            for (int j = tot - 1; j >= 0; j--)
            {
                if (base[j] == 0)
                {
                    int MIN = (1 << j);
                    int MAX = (1 << (j + 1)) - 1;

                    int pos1 = -1, pos2 = -1;

                    l = 1, r = n, mid;
                    while (l <= r)
                    {
                        mid = (l + r) / 2;
                        if (a[mid] >= MIN) r = mid - 1, pos1 = mid;
                        else l = mid + 1;
                    }

                    l = 1, r = n, mid;
                    while (l <= r)
                    {
                        mid = (l + r) / 2;
                        if (a[mid] <= MAX) l = mid + 1, pos2 = mid;
                        else r = mid - 1;
                    }

                    if (pos1 != -1 && pos2 != -1) ans = ans + (long long)(pos2 - pos1 + 1);
                }
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}

 

posted @ 2016-02-22 19:00  Fighting_Heart  阅读(312)  评论(0编辑  收藏  举报