【学习笔记】[ZJOI2019] 开关

之前没认真学 F W T FWT FWT可惜了😅

首先要做过这道题 [AGC034F] RNG and XOR

考虑 I F W T IFWT IFWT算法的本质🤔

之前我们注意到将 k k k的顺序调换并不会影响结果,也就是说只要做一遍 F W T FWT FWT,然后再除以 2 n 2^n 2n就是答案。

考虑优化🤔,发现从 P ^ i \widehat P_i P i变成 P ^ i + 2 j \widehat P_{i+2^j} P i+2j相当于整体偏移一个定值,可以用背包记录!最后再记录一下奇偶性就好了!

复杂度 O ( n ∑ p ) O(n\sum p) O(n∑p)。

remark \text{remark} remark 感觉这部分算法的性质蛮多的!

cpp 复制代码
#include<bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define db double
using namespace std;
const int mod=998244353;
const int N=1e5+5;
int n,a[105],p[105],s;
ll now[N][2],nxt[N][2],res;
void add(ll &x,ll y){
    x=(x+y)%mod;
}
ll fpow(ll x,ll y=mod-2){
    ll z(1);
    for(;y;y>>=1){
        if(y&1)z=z*x%mod;
        x=x*x%mod;
    }return z;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>n;for(int i=0;i<n;i++)cin>>a[i];
    for(int i=0;i<n;i++)cin>>p[i],s+=p[i];
    now[2*s][0]=1;
    for(int i=0;i<n;i++){
        memset(nxt,0,sizeof nxt);
        for(int j=0;j<=2*s;j++){
            for(int k=0;k<2;k++){
                if(now[j][k]){
                    add(nxt[j][k],now[j][k]);
                    add(nxt[j-2*p[i]][k^a[i]],now[j][k]);
                }
            }
        }
        memcpy(now,nxt,sizeof nxt);
    }ll mul=fpow(s);
    for(int i=0;i<=2*s;i++){
        if(now[i][1]){
            add(res,2*fpow(1-(i-s)*mul%mod)*now[i][1]%mod);
        }
    }
    cout<<(res+mod)%mod;
}
相关推荐
星空的资源小屋16 小时前
跨平台下载神器ArrowDL,一网打尽所有资源
javascript·笔记·django
Xudde.16 小时前
Quick2靶机渗透
笔记·学习·安全·web安全·php
AA陈超17 小时前
Git常用命令大全及使用指南
笔记·git·学习
麦麦在写代码18 小时前
前端学习5
前端·学习
愚戏师18 小时前
Python3 Socket 网络编程复习笔记
网络·笔记
降临-max19 小时前
JavaSE---网络编程
java·开发语言·网络·笔记·学习
大白的编程日记.20 小时前
【计算网络学习笔记】MySql的多版本控制MVCC和Read View
网络·笔记·学习·mysql
IMPYLH21 小时前
Lua 的 require 函数
java·开发语言·笔记·后端·junit·lua
u***42071 天前
Golang 构建学习
开发语言·学习·golang
车载测试工程师1 天前
CAPL学习-IP API函数-2
网络·学习·tcp/ip·capl·canoe