zoukankan      html  css  js  c++  java
  • UOJ #310 黎明前的巧克力 FWT dp

    LINK:黎明前的巧克力

    我发现 很多难的FWT的题 都和方程有关.

    上次那个西行寺无余涅槃 也是各种解方程...(不过这个题至今还未理解。

    考虑dp 容易想到f[i][j][k]表示 第一个人得到巧克力的状态为j 第二个人为k的方案数。

    期望得分0。

    观察状态转移和最终的目标状态 可以将状态降维 变成f[i][j]表示两个人异或的结果为j的方案数。

    这样复杂度是(ncdot W)的 其中W为值域.

    观察转移 可以发现是一个异或卷积的形式 所以复杂度就变成了(mcdot Wcdot logW) 其中m为数字不同的个数.

    不过上面这种方法可以 做数字相同的有很多的情况.

    考虑正解 观察在做FWT的时候 每个数字(a_i)对FWT后的数组每一位贡献要么为2 要么为-2 而0位永远贡献为1.

    所以FWT的数组每个位置要么为-1 要么为3.

    显然我们只关心最后的乘积数组上有多少个-1 和 3.

    可以发现 -1和3的数量固定 有(cnt_3+cnt_{-1}=n)

    只要再对每一位列出一个方程就能快速求出每个位置上的值了.

    考虑3和-1的和 有 FWT的和等于和的FWT.

    所以对于所有数字放在同一个数组上进行FWT就可以得到(3cdot cnt_3-cnt_{-1}=b_i)

    然后解方程 就可以得到每个位置上的数字是多少了.

    const int MAXN=1100000,INV=(mod+1)/2;
    int n,maxx,lim;
    int a[MAXN],b[MAXN];
    inline int ksm(int b,int p)
    {
    	int cnt=1;
    	while(p)
    	{
    		if(p&1)cnt=(ll)cnt*b%mod;
    		b=(ll)b*b%mod;p=p>>1;
    	}
    	return cnt;
    }
    inline void FWT(int *a,int op)
    {
    	for(int len=2;len<=lim;len=len<<1)
    	{
    		int mid=len>>1;
    		for(int j=0;j<lim;j+=len)
    		{
    			for(int i=0;i<mid;++i)
    			{
    				int x=a[i+j],y=a[i+j+mid];
    				if(op==1)a[i+j]=(x+y)%mod,a[i+j+mid]=(x-y+mod)%mod;
    				else a[i+j]=(ll)(x+y)*INV%mod,a[i+j+mid]=(ll)(x-y+mod)*INV%mod;
    			}
    		}
    	}
    }
    int main()
    {
    	freopen("1.in","r",stdin);
    	get(n);lim=1;
    	rep(1,n,i)
    	{
    		int get(x);
    		if(x>maxx)maxx=x;
    		a[x]+=2;++a[0];
    	}
    	while(lim<=maxx)lim=lim<<1;
    	FWT(a,1);
    	rep(0,lim-1,i)
    	{
    		int ww=(ll)(a[i]+n)*INV%mod*INV%mod;
    		int cc=(n-ww+mod)%mod;
    		if(cc&1)b[i]=mod-ksm(3,ww);
    		else b[i]=ksm(3,ww);
    	}
    	FWT(b,-1);put((b[0]-1+mod)%mod);
    	return 0;
    }
    
  • 相关阅读:
    JavaScript基础知识(数组的方法)
    JavaScript基础知识(字符串的方法)
    JavaScript基础知识(Number的方法)
    JavaScript基础知识(函数)
    JavaScript基础知识(三个判断、三个循环)
    JavaScript基础知识(数据类型)
    JavaScript基础知识(初识JS)
    iOS开发--Swift 基于AFNetworking 3.0的网络请求封装
    iOS开发--Swift 如何完成工程中Swift和OC的混编桥接(Cocoapods同样适用)
    如何为Swift进行宏定义
  • 原文地址:https://www.cnblogs.com/chdy/p/13137490.html
Copyright © 2011-2022 走看看