ABC367G-Sum of (XOR^K or 0)

2024-08-27 17:12
文章标签 sum xor abc367g

本文主要是介绍ABC367G-Sum of (XOR^K or 0),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第一次学会多项式的题目。

题意:
n n n个数的多重集 S S S,设 S ′ ⊆ S , f ( A ) = [ ∣ A ∣ = t m , t ∈ Z ] ( X O R a i ∈ a a i ) k S' \subseteq S,f(A)=[|A| =tm,t\in Z](XOR_{a_i\in a}ai)^k SS,f(A)=[A=tm,tZ](XORaiaai)k,求 ∑ S ′ ⊆ S f ( S ′ ) \sum_{S'\subseteq S} f(S') SSf(S)

我们统计出每个异或值出现多少次,记为 f ( x ) , x ∈ [ 0 , 2 20 − 1 ] f(x),x\in[0,2^{20}-1] f(x),x[0,2201]

用多项式来表示,有 f ( a ) = [ x a y 0 ] ∏ i = 1 n ( 1 + x a i y ) f(a)=[x^ay^0]\prod_{i=1}^n(1+x^{a_i}y) f(a)=[xay0]i=1n(1+xaiy),我们对 x x x做异或卷积,对 y y y做模m的卷积。

不妨把y看成常数,满足 y m = 0 ( m o d 998244353 ) y^m=0 (\mod 998244353) ym=0(mod998244353),然后对每个 ( 1 + y x a i ) (1+yx^{a_i}) (1+yxai)进行FWT,然后点乘起来,最后再求一次逆,但是这样是 O ( n 2 ) O(n^2) O(n2),现在思考如何化简。

我们知道多项式 g ( x ) = 1 g(x)=1 g(x)=1的FWT是全1, h ( x ) = x t h(x)=x^t h(x)=xt的FWT每一项要么是1要么是-1,如果我们知道在求完FWT第 i i i位有多少个多项式为1,设有 c i c_i ci个,那么这一项就是 [ y 0 ] ( 1 + y ) c i ( 1 − y ) n − c i [y^0](1+y)^{c_i}(1-y)^{n-c_i} [y0](1+y)ci(1y)nci,这要预处理一下就能求了。

现在考虑怎么求每一项有多少个1,我们直接把所有的数放进要进行FWT的数组,即考虑多项式 ∑ i = 1 n x a i \sum_{i=1}^n x^{a_i} i=1nxai,设有x个1,y个-1,那么FWT以后的答案是 x − y x-y xy,又知道 x + y = n x+y=n x+y=n,所以可以解出变量。

#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define dwn(i,x,y) for(int i=x;i>=y;i--)
#define ll long long
using namespace std;
template<typename T>inline void qr(T &x){x=0;int f=0;char s=getchar();while(!isdigit(s))f|=s=='-',s=getchar();while(isdigit(s))x=x*10+s-48,s=getchar();x=f?-x:x;
}
int cc=0,buf[31];
template<typename T>inline void qw(T x){if(x<0)putchar('-'),x=-x;do{buf[++cc]=int(x%10);x/=10;}while(x);while(cc)putchar(buf[cc--]+'0');
}
const int N=2e5+10,mod=998244353;
int power(int a,int b){int ret=1;while(b){if(b&1)ret=1ll*ret*a%mod;a=1ll*a*a%mod;b>>=1;}return ret;
}
int n,m,k;
int a[N];ll A[(1<<20)+10];
int s1[N][110],s2[N][110];
int f[N];
void XOR(ll *f,int type=1){int n=1<<20;for(int o=2,k=1;o<=n;o<<=1,k<<=1)for(int i=0;i<n;i+=o)for(int j=0;j<k;j++){ll x=f[i+j];ll y=f[i+j+k];if(type==1){f[i+j]=x+y;f[i+j+k]=x-y;}else{f[i+j]=(x+y)%mod;f[i+j+k]=((x-y)%mod+mod)%mod;f[i+j]=1ll*f[i+j]*type%mod;f[i+j+k]=1ll*f[i+j+k]*type%mod;}}
}
void solve(){qr(n),qr(m),qr(k);rep(i,1,n){qr(a[i]);A[a[i]]++;}s1[0][0]=1;s2[0][0]=1;rep(i,1,n){rep(j,0,m-1){int k=j?j-1:m-1;s1[i][j]=(s1[i-1][j]+s1[i-1][k])%mod;s2[i][j]=(s2[i-1][j]-s2[i-1][k]+mod)%mod;}}rep(i,0,n){rep(j,0,m-1){int t=j?m-j:0;f[i]=(f[i]+1ll*s1[i][j]*s2[n-i][t]%mod)%mod;}}XOR(A);rep(i,0,(1<<20)-1){// cout<<(A[i]+n)/2<<endl;A[i]=f[(A[i]+n)/2];}XOR(A,power(2,mod-2));int ans=0;rep(i,0,(1<<20)-1)if(A[i]){// cout<<A[i]<<" ";ans=(ans+1ll*A[i]*power(i,k)%mod)%mod;}qw(ans);puts("");
}
int main(){int tt;tt=1;while(tt--)solve();return 0;
}

这篇关于ABC367G-Sum of (XOR^K or 0)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112274

相关文章

最大流=最小割=最小点权覆盖集=sum-最大点权独立集

二分图最小点覆盖和最大独立集都可以转化为最大匹配求解。 在这个基础上,把每个点赋予一个非负的权值,这两个问题就转化为:二分图最小点权覆盖和二分图最大点权独立集。   二分图最小点权覆盖     从x或者y集合中选取一些点,使这些点覆盖所有的边,并且选出来的点的权值尽可能小。 建模:     原二分图中的边(u,v)替换为容量为INF的有向边(u,v),设立源点s和汇点t

如何导入sun.misc.BASE64Encoder和sum.misc.BASE64Decoder

右击项目名--->Build Path--->Configure Build Path...--->java Build Path--->Access rules:1 rule defined,added to all librar...   --->Edit --->Add...

18. 4 Sum

题目: 解答: 与之前的三数之和的解法类似,也是先排序,然后不断剔除不可能的条件,最后两个参数,通过两头求和计算得出。 代码: class Solution {public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> result;int len = nums.size

apt-get update更新源时,出现“Hash Sum mismatch”问题

转载自:apt-get update更新源时,出现“Hash Sum mismatch”问题 当使用apt-get update更新源时,出现下面“Hash Sum mismatch”的报错,具体如下: root@localhost:~# apt-get update ...... ...... W: Failed to fetch http://us.archive.ubuntu.com/ub

[LeetCode] 303. Range Sum Query - Immutable

题:https://leetcode.com/problems/range-sum-query-immutable/description/ 题目 Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive. Example: Given nums

[LeetCode] 64. Minimum Path Sum

题:https://leetcode.com/problems/minimum-path-sum/description/ 题目 Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers

[LeetCode] 404. Sum of Left Leaves

题:https://leetcode.com/problems/sum-of-left-leaves/description/ 题目 Find the sum of all left leaves in a given binary tree. Example: 3/ \9 20/ \15 7There are two left leaves in the binary t

数论 --- 费马小定理 + 快速幂 HDU 4704 Sum

Sum  Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=4704   Mean:  给定一个大整数N,求1到N中每个数的因式分解个数的总和。   analyse: N可达10^100000,只能用数学方法来做。 首先想到的是找规律。通过枚举小数据来找规律,发现其实answer=pow(2,n-1);

LeetCode - 40. Combination Sum II

40. Combination Sum II  Problem's Link  ---------------------------------------------------------------------------- Mean:  给你一个待选集合s和一个数n,选出所有相加之和为n的组合.(每个元素只能选一次) analyse: 递归求解. 在递归进入

LeetCode - 39. Combination Sum

39. Combination Sum  Problem's Link  ---------------------------------------------------------------------------- Mean:  给你一个待选集合s和一个数n,让你找出集合s中相加之和为n的所有组合.(每个数可选多次) analyse: 作此题需对递归有一定的