【学习笔记】[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;
}
相关推荐
Godspeed Zhao5 小时前
从零开始学AI25——无监督学习之层次聚类
学习·机器学习·聚类
David猪大卫12 小时前
【C++修炼】map 和 set 的使用
c语言·开发语言·数据结构·c++·经验分享·笔记·学习
HPtiger12 小时前
C++ 入门笔记:从 C 到 C++ 的核心过渡(命名空间、输入输出、缺省参数、重载、引用、内联)
c语言·c++·学习
星恒随风12 小时前
MySQL 从零入门(三):表的约束详解
linux·服务器·数据库·笔记·mysql
fengci.14 小时前
CTF2MISC中等部分
开发语言·前端·学习
YueTann15 小时前
mgtv5th-baseline学习
学习
蒸蒸yyyyzwd17 小时前
从后端面经学到的 3 个知识
笔记·学习
17岁的勇气17 小时前
Unity Shader unity文档学习笔记(二十二):shader变体
笔记·学习·unity
坤坤子吖17 小时前
Linux网络编程:自定义应用层协议与 JSON 序列化
linux·服务器·网络·c++·笔记·json
路灯上の马陈19 小时前
Java 内部类 学习笔记
笔记·学习