Codeforces 1096G. Lucky Tickets【生成函数】

LINK

题目大意

很简单自己看

思路

考虑生成函数(为啥tags里面有一个dp啊)

显然,每一个指数上是否有系数是由数集中是否有这个数决定的

有的话就是1没有就是0

然后求出这个生成函数的\(\frac{n}{2}\)次方

把每一项的系数全部平方加起来。。没了


#include<bits/stdc++.h>

using namespace std;

typedef vector<int> Poly;

const int N = 3e6 + 10;
const int Mod = 998244353;
const int G = 3;

int add(int a, int b, int mod = Mod) {
  return (a += b) >= mod ? a - mod : a;
}

int sub(int a, int b, int mod = Mod) {
  return (a -= b) < 0 ? a + mod : a;
}

int mul(int a, int b, int mod = Mod) {
  return 1ll * a * b % mod;
}

int fast_pow(int a, int b, int mod = Mod) {
  int res = 1;
  for (; b; b >>= 1, a = mul(a, a, mod))
    if (b & 1) res = mul(res, a, mod);
  return res;
}

int w[N][2];

void init() {
  for (int i = 1; i < (1 << 21); i <<= 1) {
    w[i][0] = w[i][1] = 1;
    int wn = fast_pow(G, (Mod - 1) / (i << 1));
    for (int j = 1; j < i; j++)
      w[i + j][0] = mul(w[i + j - 1][0], wn);
    wn = fast_pow(G, Mod - 1 - (Mod - 1) / (i << 1));
    for (int j = 1; j < i; j++)
      w[i + j][1] = mul(w[i + j - 1][1], wn);
  }
}

void transform(int *t, int len, int typ) {
  for (int i = 0, j = 0, k; j < len; j++) {
    if (i > j) swap(t[i], t[j]);
    for (k = (len >> 1); k & i; k >>= 1) i ^= k;
    i ^= k;
  }
  for (int i = 1; i < len; i <<= 1) {
    for (int j = 0; j < len; j += i << 1) {
      for (int k = 0; k < i; k++) {
        int x = t[j + k], y = mul(t[j + k + i], w[i + k][typ]);
        t[j + k] = add(x, y);
        t[j + k + i] = sub(x, y);
      }
    }
  }
  if (typ) return;
  int invlen = fast_pow(len, Mod - 2);
  for (int i = 0; i < len; i++)
    t[i] = mul(t[i], invlen);
}

Poly fast_pow(Poly a, int b) {
  int len = 1 << (int) ceil(log2(a.size()));
  a.resize(len);
  transform(&a[0], len, 1);
  for (int i = 0; i < len; i++)
    a[i] = fast_pow(a[i], b);
  transform(&a[0], len, 0);
  return a;
}

int n, k;

int main() {
  init();
  scanf("%d %d", &n, &k);
  Poly a((int) 2e6);
  for (int i = 1; i <= k; i++) {
    int x;
    scanf("%d", &x);
    a[x] = 1;
  }
  a = fast_pow(a, n / 2);
  int ans = 0;
  for (int i = 0; i < (signed) a.size(); i++)
    ans = add(ans, mul(a[i], a[i]));
  printf("%d", ans);
  return 0;
}

原文地址:https://www.cnblogs.com/dream-maker-yk/p/10231006.html

时间: 2024-11-04 14:53:51

Codeforces 1096G. Lucky Tickets【生成函数】的相关文章

Ural 1036 Lucky Tickets

Lucky Tickets Time Limit: 2000ms Memory Limit: 16384KB This problem will be judged on Ural. Original ID: 103664-bit integer IO format: %lld      Java class name: (Any) You are given a number 1 ≤ N ≤ 50. Every ticket has its 2N-digit number. We call a

DP+高精度 URAL 1036 Lucky Tickets

题目传送门 1 /* 2 题意:转换就是求n位数字,总和为s/2的方案数 3 DP+高精度:状态转移方程:dp[cur^1][k+j] = dp[cur^1][k+j] + dp[cur][k]; 4 高精度直接拿JayYe的:) 5 异或运算的规则: 6 0⊕0=0,0⊕1=1 7 1⊕0=1,1⊕1=0 8 口诀:相同取0,相异取1 9 */ 10 #include <cstdio> 11 #include <cstring> 12 #include <string>

寒假集训.Lucky Tickets. Easy!

Lucky Tickets. Easy! Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description Background The public transport administration of Ekaterinburg is anxious about the fact that passengers don't like to pay for

CodeForces E. Lucky Array 幸运数列

CodeForces    E. Lucky Array  幸运数列 Petya loves lucky numbers. Everybody knows that lucky numbers are positive integers whose decimal representation contains only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are n

【数位DP】Codeforces Gym 100418J Lucky tickets

题意: 设性质P:一个数能够整除它二进制表示下的1的个数.求[1,N]中满足性质P的数的个数.N<=1019. 思路: 数位DP.首先这个数最多有64位,我们可以枚举1的个数x,然后求可以整除x的数的个数.设dp[i][j][k][w]表示从最高位枚举到i位,现在已经构成的数模x余多少(这里是关键,只用考虑余数),现在已经用了k个1,w=0表示现在枚举的这个数已经小于N了,w=1表示从最高位到第i位都与N相同(数位dp计算时的方法:如果当前枚举的数小于N了,那么枚举的这一位就可以任意,如果等于N

@codeforces - [email&#160;protected] Lucky Tickets

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 已知一个数(允许前导零)有 n 位(n 为偶数),并知道组成这个数的数字集合(并不一定要把集合内的数用完).求有多少种可能,使得这个数前半部分的数位和等于后半部分的数位和. 模 998244353. input 第一行两个整数:n k.表示这个数的位数以及组成这个数的数字集合大小.2

CodeForces 146A Lucky Ticket

Lucky Ticket Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 146A Description Petya loves lucky numbers very much. Everybody knows that lucky numbers are positive integers whose decimal

Codeforces 121A Lucky Sum

Lucky Sum Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Original ID: 121A64-bit integer IO format: %I64d      Java class name: (Any) Petya loves lucky numbers. Everybody knows that lucky numbers are positive int

Codeforces 109C Lucky Tree 组合计数+dfs

题目链接:点击打开链接 题意: 给定n个点的树,有边权. 定义lucky number:数字只有4或7组成 对于一个三元组(i, j, k) 若path(i,j) 路径上的数字存在lucky number && path(i,k) 路径上的数字存在lucky number 则三元组合法. 问有多少个合法的三元组. ( (i,j,k) != (i,k,j) ) 用全集-补集.dfs出每个只由 非lucky number 构成的联通块 的点数 x . 然后方法数就是 x*(x-1)*(x-2)