Fenwit FWT+数论
来源:互联网 发布:淘宝零食视频 编辑:程序博客网 时间:2024/06/10 06:03
题意
分析
这题好神啊!!!
这题大概题意就是说给出一个数组f,设c[i,j]=b[cnt(i^j)],那么答案就是
但这么做显然只有20分,而这20分是只要暴力就可以拿到的。
我们可以重新定义
那如何快速计算
FWT就是专门解决快速类似进行
FWT写起来与fft类似,比fft更简洁一点,我觉得介绍FWT比较好的博文是这篇和这篇。至于要自己推一遍的话,这个坑就留着改天再补好了。
有了FWT这个神器之后,再回到这题。现在问题在于如何计算
又注意到在做逆FWT变换的时候,由于有/2运算,而由于模数不确定,所以不一定存在逆元。那么我们可以在做完逆FWT变换后再除以
这样就可以切掉这题啦啦啦!!!
代码
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const int N=300005;int n,m,p,bin[20];char ch[1005];LL c[N],f[N],b[N],phip,t;int read(){ int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}LL READ(LL mo){ scanf("%s",ch);int flag=0,len=strlen(ch);LL now=0; for (int i=0;i<len;i++) { now=now*10+ch[i]-'0'; if (now>=mo) flag=1; now%=mo; } if (flag) return now+mo; else return now;}LL mul(LL x,LL y,LL mo){ LL tmp=(x*y-(LL)((double)x*y/mo+0.1)*mo)%mo; if (tmp<0) tmp+=mo; return tmp;}LL ksm(LL x,LL y,LL mo){ LL ans=1; while (y) { if (y&1) ans=mul(ans,x,mo); x=mul(x,x,mo);y>>=1; } return ans;}int cnt(int x){ int ans=0; while (x) ans++,x-=x&(-x); return ans;}int get_phi(int n){ int w=n,tmp=n; for (int i=2;i*i<=n;i++) if (tmp%i==0) { w=w/i*(i-1); while (tmp%i==0) tmp/=i; } if (tmp>1) w=w/tmp*(tmp-1); return w;}void fwt(LL *a,int n,LL mo){ for (int i=1;i<n;i<<=1) for (int j=0;j<n;j+=(i<<1)) for (int k=0;k<i;k++) { LL x=a[j+k],y=a[j+k+i]; a[j+k]=(x+y)%mo;a[j+k+i]=(x-y+mo)%mo; }}void dwt(LL *a,int n,LL mo){ for (int i=1;i<n;i<<=1) for (int j=0;j<n;j+=(i<<1)) for (int k=0;k<i;k++) { LL x=a[j+k],y=a[j+k+i]; a[j+k]=(x+y)%mo;a[j+k+i]=(x-y+mo)%mo; }}int main(){ m=read();p=read(); bin[0]=1; for (int i=1;i<=m;i++) bin[i]=bin[i-1]*2; phip=get_phi(p); if (p%2==0) phip=(LL)phip*bin[m]; else phip=(LL)phip*bin[m-1]; t=READ(phip); for (int i=0;i<bin[m];i++) f[i]=read(); for (int i=0;i<=m+1;i++) b[i]=read(); for (int i=0;i<bin[m];i++) c[i]=b[cnt(i)]; fwt(c,bin[m],(LL)p*bin[m]); fwt(f,bin[m],(LL)p*bin[m]); for (int i=0;i<bin[m];i++) c[i]=ksm(c[i],t,(LL)p*bin[m]); for (int i=0;i<bin[m];i++) f[i]=mul(f[i],c[i],(LL)p*bin[m]); dwt(f,bin[m],(LL)p*bin[m]); for (int i=0;i<bin[m];i++) printf("%lld\n",f[i]/bin[m]); return 0;}
阅读全文
1 0
- Fenwit FWT+数论
- FWT
- FWT
- 【HNOI2016模拟4.4】Fenwit
- 【JZOJ4425】【HNOI2016模拟4.4】Fenwit
- FWT总结
- FWT 模板
- FWT板子
- bzoj4589 FWT
- fwt模版
- FWT模板
- FWT 笔记
- TC SRM518 NIM (FWT)
- 法法塔!【fft&fwt】
- PE 560 【博弈】【fwt】
- FWT 详解 知识点
- FFT&&FWT&&NTT
- [FWT] Codeforces663E .Binary Table
- HUD 1003
- python学习之高阶函数
- 帮助理解形参的小例子--判断输入的字符是否为纯数字
- linux下I2C驱动架构全面分析
- objective-C学习笔记(四)函数成员:方法(函数)
- Fenwit FWT+数论
- 木棍
- libjpeg库的安装、移植、交叉编译环境、编解码。
- POJ 3468A Simple Problem with Integers(线段树)
- 协方差的意义和计算公式
- <html>1.1初识html
- 每日一刷——逆置单链表&&查找倒数第k个节点&&Add函数
- Oracle之SQL优化-索引的基本原理(二)
- 文本的控件的基本属性