All bus tickets in Berland have their numbers. A number consists of 44443

are not.

A ticket is lucky if the sum of first 2

digits is equal to the sum of remaining 2

digits.

Calculate the number of different lucky tickets in Berland. Since the answer may be big, print it modulo 998244353

.

Input

The first line contains two integers n

and n

is even.

The second line contains a sequence of pairwise distinct integers k

)

— the digits that may be used in ticket numbers. The digits are given in arbitrary order.

Output

Print the number of lucky ticket numbers, taken modulo 998244353

.

Examples
Input
Copy
4 2
1 8
Output
Copy
6
Input
Copy
20 1
6
Output
Copy
1
Input
Copy
10 5
6 1 4 0 3
Output
Copy
569725
Input
Copy
1000 7
5 4 0 1 8 3 2
Output
Copy
460571165
Note

In the first example there are 6

lucky ticket numbers: 8888

.

There is only one ticket number in the second example, it consists of 20

1.

 

题意:给定你K种数可以选,问你有多少排列,使得前半部分的和等于后半部分的和。

思路:我们枚举“和”的大小,令A[i]表示长度为N/2时和为i的方案数,那么答案就是所有的A[i]*A[i];

怎么就Ai呢,就是一个多项式(P0.X0+P1*X1+...*P9*X9)^(N/2);p是0或者1;

多项式的N次,我们可以用快速幂+FFT来加速,这里要取模,写的NTT。然后就是可以直接一次DFT+快速幂+IDFT。

(之前纠结过为什么可以一次DFT就搞定了,而不是logN次,现在看来是对的,正确性我还需要学习一下。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
#define ll long long
const int G=3;
const int maxn=2148576;
const int Mod=998244353;
int mod,n,k,rev[maxn],lim,ilim,s,wn[maxn+1];
std::vector<int> v;
inline int pow(int x, int y) {
    int ans=1;
    for(;y;y>>=1,x=(ll)x*x%mod)
      if(y&1) ans=(ll)ans*x%mod;
    return ans;
}
inline int& up(int& x, int y) { if ((x+=y)>=mod) x-=mod; return x; }
inline void NTT(int* A, int typ) {
    rep(i,0,lim-1) if (i<rev[i]) swap(A[i], A[rev[i]]);
    for (int i=1;i<lim;i+=i) {
        const int t=lim/i/2;
        for (int j=0;j<lim;j+=i+i) {
            for (int k=0;k<i; k++) {
                int w=typ?wn[t*k]:wn[lim-t*k];
                int x=A[k+j],y=(ll)w*A[k+j+i]%mod;
                up(A[k+j],y),up(A[k+j+i]=x,mod-y);
            }
        }
    }
    if (!typ) rep(i,0,lim-1) A[i]=(ll)ilim*A[i]%mod;
}
inline void init(int len,int tmod) {
    mod=tmod; lim=1; s=-1;
    while(lim<len) lim+=lim,s++;  ilim=pow(lim,mod-2);
    rep(i,0,lim-1) rev[i]=rev[i>>1]>>1|(i&1)<<s;
    int w=pow(G,(mod-1)/len);
    wn[0]=1;
    rep(i,1,lim) wn[i]=(ll)(wn[i-1])*w%mod;
}
int A[maxn];
int main() {
    scanf("%d%d",&k,&n); k/=2;
    int x,ans=0; rep(i,1,n) scanf("%d",&x), A[x]=B[x]=1;
    init(2097152, 998244353);
    NTT(A, 1);
    rep(i,0,lim-1) A[i]=pow(A[i],k);
    NTT(A, 0);
    rep(i,0,2000000) (ans+=(ll)A[i]*A[i]%Mod)%=Mod;
    printf("%d\n",ans);
    return 0;
}

 

相关文章:

  • 2022-12-23
  • 2021-07-25
  • 2022-12-23
  • 2022-01-14
  • 2021-09-12
  • 2022-12-23
  • 2021-05-19
  • 2022-12-23
猜你喜欢
  • 2021-10-25
  • 2022-03-06
  • 2021-06-24
  • 2022-03-10
  • 2022-12-23
  • 2021-10-07
  • 2022-12-23
相关资源
相似解决方案