UESTC 84 Binary Operations(位运算+DP)

来源:互联网 发布:雨田软件 编辑:程序博客网 时间:2024/05/01 00:37

http://acm.uestc.edu.cn/#/problem/show/84
弱校联萌的题,比赛时没出,赛后看了题解补的。
题目大意是给出一个数列,输出任意选择一段连续子序列&、|、^的期望值。
首先将每一个数字按二进制位分解,然后对于每一种运算DP求期望,具体细节见代码。

#include <cstdio>#include <algorithm>typedef long long LL;using namespace std;const int maxn = 100010;LL a[maxn];int And[maxn], Or[maxn], Xor[maxn];int main() {    int t, tt = 0; scanf("%d", &t);    while (t--) {        int n; scanf("%d", &n);        for (int i = 1; i <= n; ++i)            scanf("%lld", &a[i]);        double ansAnd = 0.0, ansOr = 0.0, ansXor = 0.0, tmp = LL(n+1)*n/2.0;        for (int i = 0; i < 31; ++i) {            fill(And, And + n + 1, 0);            fill(Or, Or + n + 1, 0);            fill(Xor, Xor + n + 1, 0);            LL sumAnd = 0, sumOr = 0, sumXor = 0;            for (int j = 1; j <= n; ++j) {                if ((1LL << i) & a[j]) {                    And[j] = And[j - 1] + 1;                    Or[j] = j;                    Xor[j] = j - Xor[j - 1];                } else {                    And[j] = 0;                    Or[j] = Or[j - 1];                    Xor[j] = Xor[j - 1];                }                sumAnd += And[j];                sumOr += Or[j];                sumXor += Xor[j];            }            ansAnd += (1LL << i) * sumAnd / tmp;            ansOr += (1LL << i) * sumOr / tmp;            ansXor += (1LL << i) * sumXor / tmp;        }        printf("Case #%d: %.6lf %.6lf %.6lf\n", ++tt, ansAnd, ansOr, ansXor);    }    return 0;}
0 0
原创粉丝点击