• 位运算 UEST 84 Binary Operations


    题目传送门

    题意:所有连续的子序列的三种位运算计算后的值的和的期望分别是多少

    分析:因为所有连续子序列的组数有n * (n + 1) / 2种,所以要将他们分类降低复杂度,以ai为结尾的分成一组,至于具体的做法,我觉得这篇题解已经写的很详细了,UESTC 1709 Binary Operations

    吐槽一下,题解的代码交上去是TLE的,至今不知道为何,我写的是WA,将所有类型改成ll才AC。。。

    /************************************************
    * Author        :Running_Time
    * Created Time  :2015/10/8 星期四 17:43:10
    * File Name     :B.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int N = 5e4 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    const double EPS = 1e-8;
    ll a[N], num[35], s[N];
    
    void add(int x) {
        int k = 0;
        while (x)   {
            if (x & 1)  num[k]++;
            x >>= 1;    k++;
        }
    }
    
    int main(void)    {
        ll T, cas = 0; scanf ("%d", &T);
        while (T--) {
            ll n;  scanf ("%lld", &n);
            for (int i=0; i<n; ++i)    scanf ("%lld", &a[i]);
            memset (num, 0, sizeof (num));
            memset (s, 0, sizeof (s));
            double ans1 = 0, ans2 = 0, ans3 = 0;
            ll tmp;
            for (int i=0; i<n; ++i) {
                s[i] = a[i];
                if (i == 0) add (a[i]);
                else    {
                    tmp = a[i];
                    for (int j=0; j<31; ++j)    {
                        if (tmp & (1 << j)) {}
                        else num[j] = 0;
                        s[i] += (num[j] * (1 << j));
                    }
                    add (a[i]);
                }
                ans1 += s[i];
            }
            
            memset (num, 0, sizeof (num));
            for (int i=0; i<n; ++i) {
                s[i] = a[i];
                if (i == 0) add (a[i]);
                else    {
                    tmp = a[i];
                    for (int j=0; j<31; ++j)    {
                        if (tmp & (1 << j)) num[j] = i;
                        s[i] += (num[j] * (1 << j));
                    }
                    add (a[i]);
                }
                ans2 += s[i];
            }
            
            memset (num, 0, sizeof (num));
            for (int i=0; i<n; ++i) {
                s[i] = a[i];
                if (i == 0) add (a[i]);
                else    {
                    tmp = a[i];
                    for (int j=0; j<31; ++j)    {
                        if (tmp & (1 << j)) num[j] = i - num[j];
                        s[i] += (num[j] * (1 << j));
                    }
                    add (a[i]);
                }
                ans3 += s[i];
            }
            ll len = n * (n + 1) / 2;
            printf ("Case #%lld: %.6lf %.6lf %.6lf
    ", ++cas, ans1 / len, ans2 / len, ans3 / len);
        }
    
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    编程题#2: 魔兽世界之二:装备
    程序设计实习MOOC / 继承和派生——编程作业 第五周程序填空题1
    【转】C++动态创建二维数组,二维数组指针
    HDU-2571命运
    HDU-1203 I NEED A OFFER!
    HDU-1003 Max Sum
    HDU2196-Computer
    HDU-1520 Anniversary party
    ChineseHelper(获取汉字字符串的首拼)
    车牌号正则表达式(新能源车牌)
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4867457.html
Copyright © 2020-2023  润新知