CF2020E. Expected Power

原题链接

前言

不是 \(\Theta (1024 \times n)\) 真能水过去?
So what's the point of allowing \(\Theta (1024 \times n)\) solutions to E????

算法

动态规划, 期望.

思路

读题, 发现 \(1 \le a_i \le 1023\).

这说明什么? 说明异或后的值一定 \(\le 1023\) !.

定义 \(f_{i,j}\) 表示前 \(i\) 个数中, 选出来的数按位异或的值为 \(j\) 的概率.

那么便可以十分平凡地进行转移, 枚举每个数取或者不取.

时间复杂度 \(\Theta (1024 \times n)\), 时限给的 4s, 完全够了.

#pragma GCC optimize("Ofast")

#include "iostream"

using namespace std;

const int N = 2e5 + 10, M = 1e3 + 50, mod = 1e9 + 7;

#define int long long

int n;
int a[N], p[N];
int f[2][M];

int qpow(int x, int y)
{
    int ret = 1;
    for (; y; y >>= 1, x = x * x % mod)
        if (y & 1)
            ret = ret * x % mod;
    return ret;
}

void init()
{
    cin >> n;
#pragma GCC unroll 8
    for (int i = 1; i <= n; ++i)
        cin >> a[i];
#pragma GCC unroll 8
    for (int i = 1; i <= n; ++i)
        cin >> p[i], p[i] = p[i] * qpow(1e4, mod - 2) % mod;
    return;
}

void calculate()
{
    for (int i = 0; i ^ 1024; ++i)
        f[0][i] = f[1][i] = 0;
    f[0][0] = 1;
    int nw = 1;
#pragma GCC unroll 8
    for (int i = 1; i <= n; ++i)
    {
        int p1 = p[i] % mod, p2 = (1 - p1 + mod) % mod;
        for (int j = 0; j ^ 1024; ++j)
            f[nw][j] = f[nw ^ 1][j] * p2 % mod;
        for (int j = 0; j ^ 1024; ++j)
            f[nw][j ^ a[i]] = (f[nw][j ^ a[i]] + f[nw ^ 1][j] * p1) % mod;
        nw ^= 1;
    }
    int ans = 0;
    for (int i = 0; i ^ 1024; ++i)
        ans = (ans + f[nw ^ 1][i] * i * i % mod) % mod;
    cout << ans << '\n';
}

void solve()
{
    init();
    calculate();
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int T;
    cin >> T;
    while (T--)
        solve();
    return 0;
}
posted @   Steven1013  阅读(4)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示