首页 > 其他分享 >[ABC212H] Nim Counting

[ABC212H] Nim Counting

时间:2023-12-31 21:34:51浏览次数:31  
标签:等比数列 Nim int 对点值 ll 求和 FWT ABC212H Counting

题目链接

题目本质就是对一个多项式 \(F\) 进行等比数列求和得到 \(G\)(\(F_i\) 表示 \(i\) 在序列 \(A\) 中的出现次数),求 \(G\) 所有下标 \(>0\) 的位置的权值和。

显然,\(M\) 固定就可以直接做了。但 \(M\) 不固定,所以我们只能暴力枚举 \(M\) 并进行 \(N\) 次 FWT 卷积。复杂度显然不满足需求。

容易想到一个经典的套路就是,我们可以直接对点值进行操作。于是我们 FWT 完后对所有点值进行等比数列求和,再 IFWT 回去就行了。

值得一提的是,在实现对点值的等比数列求和时,需特判点值为 \(1\) 的情况。

点击查看代码
#include <bits/stdc++.h>
#define FL(i, a, b) for(int i = (a); i <= (b); ++i)
#define FR(i, a, b) for(int i = (a); i >= (b); --i)
using namespace std;
typedef long long ll;
constexpr int N = 1 << 16 + 10;
constexpr ll mod = 998244353, inv2 = (mod + 1) >> 1;
int n = 1 << 16, m, k; ll ans, a[N];
ll Pow(ll a, ll b){
    ll ans = 1;
    while(b){
        if(b & 1) (ans *= a) %= mod;
        (a *= a) %= mod, b >>= 1;
    }
    return ans;
}
void FWT_xor(ll f[], ll x = 1){
    for(int b = 2, k = 1; b <= n; b <<= 1, k <<= 1){
        for(int i = 0; i < n; i += b){
            for(int j = 0; j < k; ++j){
                f[i + j] += f[i + j + k];
                f[i + j + k] = f[i + j] - f[i + j + k] * 2 % mod + mod;
                (f[i + j] *= x) %= mod, (f[i + j + k] *= x) %= mod;
            }
        }
    }
}
int main(){
    scanf("%d%d", &k, &m);
    FL(i, 1, m){int x; scanf("%d", &x), ++a[x];}
    FWT_xor(a);
    FL(i, 0, n - 1){
        if(a[i] == 1) a[i] = k;
        else a[i] = ((Pow(a[i], k + 1) + mod - 1) * Pow(a[i] + mod - 1, mod - 2) + mod - 1) % mod;
    }
    FWT_xor(a, inv2);
    FL(i, 1, n - 1) ans += a[i];
    printf("%lld\n", (ans % mod + mod) % mod);
    return 0;
}

标签:等比数列,Nim,int,对点值,ll,求和,FWT,ABC212H,Counting
From: https://www.cnblogs.com/zac2010/p/17938015

相关文章

  • 在pycharm中调用manim
    1.pycharm新建两个文件,一个manimCE.py并输入下列代码:frommanimimport*classOpeningManim(Scene):defconstruct(self):config.tex_template=TexTemplateLibrary.ctex#设置中文显示title=Tex(r"Thisissome\LaTeX")basel=MathTe......
  • CF1884D Counting Rhyme 题解
    Problem-D-CodeforcesCountingRhyme-洛谷法1:我们之前肯定看过这样一道非常经典的题:求\(a_i\)中有多少对\((i,j)\),满足\(\gcd(a_i,a_j)=1\)\(n\leq10^6\)这题是莫反板子题,但显然可以不用莫反做。先不说这题怎么做,我们发现这道题和CF1884D的不同之处在......
  • [LeetCode] 1578. Minimum Time to Make Rope Colorful
    Alicehasnballoonsarrangedonarope.Youaregivena0-indexedstringcolorswherecolors[i]isthecoloroftheithballoon.Alicewantstheropetobecolorful.Shedoesnotwanttwoconsecutiveballoonstobeofthesamecolor,sosheasksBobfor......
  • 使用Element.animate()实现动画
    Element.animate()实现<divid="app"><button@click="startAmi">开始</button><p>{{msg}}</p></div><scriptsrc="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><s......
  • CF1887C Minimum Array 题解
    Problem-1887C-CodeforcesMinimumArray-洛谷有点被降智了/ll首先区间修改显然先转化成差分序列单点修改。显然对于相同的操作序列,\(a_i\)的取值对答案无影响,因此我们可以先让\(a_i\)全部取\(0\),最后再加回来即可假如说操作到某一时刻,\(a_i\)的值中第一个......
  • 浅谈 Nim game(尼姆博弈)
    首先,我们需要了解\(Nim\)游戏是什么东西。\(Nim\)游戏指:两个人,有\(n\)堆数,每堆有\(a_i\)个,每次可以且仅可以取一堆中的若干个数,求问先手有没有必胜策略(当然两个人都足够聪明)。首先,先研究显然的必胜策略。比如,我们要得到\(0\)这个数,那么当你取完时还剩下\(0\)个。然......
  • CF1881F Minimum Maximum Distance 题解
    因为白点对\(f_i\)没有贡献,所以可以重构出一棵原树的子树,使得所有的叶子都为标记点且标记点数量不变(没有删去标记点)。因为没有标记被删去且结构不变,所以这棵树的答案与原树答案相同。现在,对于所有节点,到它距离最大的标记点一定在叶子上。那么问题就变为:求出树上任意一点到所有......
  • Flutter AnimatedList 实现动态列表
    import'dart:async';import'package:flutter/material.dart';finalGlobalKey_globalKey=GlobalKey();classMyAnimatedListextendsStatelessWidget{constMyAnimatedList({super.key});@overrideWidgetbuild(BuildContextcont......
  • P2197 【模板】Nim 游戏
    原题链接题解说的很详细,我来讲讲我对为什么要用异或判断的想法异或为零是先手必败状态的一个属性,我们通过属性来判断类别。代码#include<bits/stdc++.h>usingnamespacestd;intmain(){intt;cin>>t;while(t--){intn;cin>>n;......
  • Unity无法显示animator面板,如何解决?
    步骤:点击动画的主体;右侧Inspector面板找到Animator,双击Controller中的对象;左上角即可显示animator面板。总结:不行就双击!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!遇事不决就双击~~......