bzoj4589: Hard Nim fwt

题意:求n个m以内的素数亦或起来为0的方案数
题解:fwt板子题,先预处理素数,把m以内素数加一遍(下标),然后fwt之后快速幂即可,在ifwt之后a【0】就是答案了

/**************************************************************
    Problem: 4589
    User: walfy
    Language: C++
    Result: Accepted
    Time:4984 ms
    Memory:1928 kb
****************************************************************/

//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize(4)
//#pragma GCC optimize("unroll-loops")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include<bits/stdc++.h>
#define fi first
#define se second
#define db double
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define ld long double
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
//#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define fin freopen("a.txt","r",stdin)
#define fout freopen("a.txt","w",stdout)
#define fio ios::sync_with_stdio(false);cin.tie(0)
template<typename T>
inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
template<typename T>
inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}

using namespace std;

const double eps=1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int N=50000+10,maxn=400000+10,inf=0x3f3f3f3f;

int prime[N],cnt,a[N*2];
bool mark[N];
int inv=qp(2,mod-2);
void init()
{
    for(int i=2;i<N;i++)
    {
        if(!mark[i])prime[++cnt]=i;
        for(int j=1;j<=cnt&&i*prime[j]<N;j++)
        {
            mark[i*prime[j]]=1;
            if(i%prime[j]==0)break;
        }
    }
}
void fwt(int *a,int n,int dft)
{
    for(int i=1;i<n;i<<=1)
    {
        for(int j=0;j<n;j+=(i<<1))
        {
            for(int k=j;k<j+i;k++)
            {
                int x=a[k],y=a[k+i];
                a[k]=(x+y)%mod;a[k+i]=(x-y+mod)%mod;
                if(dft==-1)a[k]=1ll*a[k]*inv%mod,a[k+i]=1ll*a[k+i]*inv%mod;
            }
        }
    }
}
int main()
{
    init();
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        memset(a,0,sizeof a);
        for(int i=1;i<=cnt&&prime[i]<=m;i++)a[prime[i]]=1;
        int len=1;while(len<=m)len<<=1;
        fwt(a,len,1);
        for(int i=0;i<=len;i++)a[i]=qp(a[i],n);
        fwt(a,len,-1);
        printf("%d\n",a[0]);
    }
    return 0;
}
/********************

********************/

原文地址:https://www.cnblogs.com/acjiumeng/p/9510868.html

时间: 2024-11-15 06:42:09

bzoj4589: Hard Nim fwt的相关文章

[bzoj4589]Hard Nim——SG函数+FWT

题目大意: Claris和NanoApe在玩石子游戏,他们有n堆石子,规则如下: Claris和NanoApe两个人轮流拿石子,Claris先拿. 每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜. 不同的初始局面,决定了最终的获胜者,有些局面下先拿的Claris会赢,其余的局面Claris会负. Claris很好奇,如果这n堆石子满足每堆石子的初始数量是不超过m的质数,而且他们都会按照最优策略玩游戏,那么NanoApe能获胜的局面有多少种. 由于答案可能很大,你只

BZOJ4589 Hard Nim(快速沃尔什变换模板)

终于抽出时间来学了学,比FFT不知道好写到哪里去. #include <cstdio> typedef long long ll; const int N=65536,p=1e9+7; int k,m,n,a[N],pi[N]; bool pr(int x) {for(int i=2;i*i<=x;i++) if(x%i==0) return 0; return 1;} ll pw(ll a,int b) {ll r=1; for(;b;b>>=1,a=a*a%p) if(b

bzoj 4589 Hard Nim —— FWT

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4589 先手必败,是一开始所有石子的异或和为0: 生成函数 (xpri[1] + xpri[2] + ... + xpri[k])n,pri[k] <= m FWT求解即可: 而且不要快速幂里面每次变换来变换去的,只有快速幂前后需要变换. 代码如下: #include<iostream> #include<cstdio> #include<cstring> #

bzoj 4589 Hard Nim——FWT

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4589 一开始异或和为0的话先手必败.有 n 堆,每堆可以填那些数,求最后异或和为0的方案数,就是一个快速幂的异或FWT. 注意快速幂的过程中对那些数组直接乘就行,不用总是FWT!!! 为什么比Zinn慢了1008ms? #include<iostream> #include<cstdio> #include<cstring> #include<algorit

@bzoj - [email&#160;protected] Hard Nim

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] n 堆石子,每堆石子的数量是不超过 m 的一个质数. 两个人玩 nim 游戏,问使后手必胜的初始局面有多少种. 模 10^9 + 7. input 多组数据.数据组数 <= 80. 每组数据一行两个正整数,n 和 m.1 <= n <= 10^9, 2 <= m <

BZOJ 3105: [cqoi2013]新Nim游戏

3105: [cqoi2013]新Nim游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1064  Solved: 624[Submit][Status][Discuss] Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴,但不能同时从超过一堆火柴中拿.拿走最后一根火柴的游戏者胜利. 本题的游

Nim 游戏、SG 函数、游戏的和

Nim游戏 Nim游戏定义 Nim游戏是组合游戏(Combinatorial Games)的一种,准确来说,属于"Impartial Combinatorial Games"(以下简称ICG).满足以下条件的游戏是ICG(可能不太严谨):1.有两名选手:2.两名选手交替对游戏进行移动(move),每次一步,选手可以在(一般而言)有限的合法移动集合中任选一种进行移动:3.对于游戏的任何一种可能的局面,合法的移动集合只取决于这个局面本身,不取决于轮到哪名选手操作.以前的任何操作.骰子的点数

BZOJ1022: [SHOI2008]小约翰的游戏John(Nim博弈)

Description 小约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有n堆石子,小约翰和他的哥哥轮流取石子,每个人取的时候,可以随意选择一堆石子,在这堆石子中取走任意多的石子,但不能一粒石子也不取,我们规定取到最后一粒石子的人算输.小约翰相当固执,他坚持认为先取的人有很大的优势,所以他总是先取石子,而他的哥哥就聪明多了,他从来没有在游戏中犯过错误.小约翰一怒之前请你来做他的参谋.自然,你应该先写一个程序,预测一下谁将获得游戏的胜利. Input 本题的输入由多组数据组成第一行包括一个整数T,

【算法功底】LeetCode 292 Nim Game

You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove th