题意:所有连续的子序列的三种位运算计算后的值的和的期望分别是多少
分析:因为所有连续子序列的组数有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\n", ++cas, ans1 / len, ans2 / len, ans3 / len); } return 0; }