zoukankan      html  css  js  c++  java
  • [atARC129F]Let's Play Tag

    假设每一次方向变化时(包括结束时)所抓的最后一个人位置(绝对值)依次为$a_{1},a_{2},...,a_{k}$,则不难得到答案为$a_{k}+\sum_{i=1}^{k-1}(3^{k-i}+3^{k-i-1})a_{i}$

    另外,$a_{1},a_{2},...,a_{k}$必然是左右交替的,但首尾并不能确定,可以暴力分类讨论

    进一步的,考虑每一个$a_{i}$​的贡献,最终可得$L_{i}$对总答案的贡献为($R_{i}$类似)
    $$
    \frac{4}{3}\sum_{i=1}^{n-1}L_{i}\sum_{x=1}^{n}\left(4{m-1\choose x-1}+{m-1\choose x-2}+3{m-1\choose x}\right)\sum_{j=1}^{x-1}9^{j}{n-i-1\choose j-1}{i-1\choose x-j-1}\\\sum_{x=1}^{n}{n-1\choose x-1}\left(5{m-1\choose x-1}+{m-1\choose x-2}+4{m-1\choose x}\right)L_{n}
    $$
    下式显然可以直接计算,上式中三个组合数相加不妨用${m-1\choose x-1}$代替,并交换$x$和$j$​的枚举顺序,即
    $$
    \frac{4}{3}\sum_{i=1}^{n-1}L_{i}\sum_{j=1}^{n-1}9^{j}{n-i-1\choose j-1}\sum_{x=j+1}^{n}{i-1\choose x-j-1}{m-1\choose x-1}
    $$
    考虑关于$x$的枚举,将${i-1\choose x-j-1}$改为${i-1\choose i-(x-j)}$,根据${n+m\choose k}=\sum{n\choose x}{m\choose k-x}$​,即${i+m-2\choose i+j-1}$

    (另外,简单分析可得$x$取到所有${i-1\choose i-(x-j)}$非0的情况)

    将组合数均用阶乘展开,并简单分类,即
    $$
    \frac{4}{3}\sum_{i=1}^{n-1}L_{i}(n-i-1)!(i+m-2)!\sum_{j=1}^{n-1}\frac{9^{j}}{(j-1)!(m-j-1)!}\cdot \frac{1}{(n-i-j)!(i+j-1)!}
    $$
    显然可以用多项式乘法处理,再使用ntt优化即可

    时间复杂度为$o(n\log n)$,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N (1<<19)
     4 #define mod 998244353
     5 #define ll long long
     6 #define Add(x,y) (x+y<mod ? x+y : x+y-mod)
     7 #define Dec(x,y) (x>=y ? x-y : x-y+mod)
     8 int n,m,ans,mi[N],rev[N],fac[N],inv[N],a[N],A[N],B[N],g[N];
     9 int C(int n,int m){
    10     if (n<m)return 0;
    11     return (ll)fac[n]*inv[m]%mod*inv[n-m]%mod;
    12 }
    13 int qpow(int n,int m){
    14     int s=n,ans=1;
    15     while (m){
    16         if (m&1)ans=(ll)ans*s%mod;
    17         s=(ll)s*s%mod,m>>=1;
    18     }
    19     return ans;
    20 }
    21 void ntt(int *a,int p=0){
    22     for(int i=0;i<N;i++)
    23         if (i<rev[i])swap(a[i],a[rev[i]]);
    24     for(int i=2,l=0;i<=N;i<<=1,l++){
    25         int s=qpow(3,(mod-1)/i);
    26         if (p)s=qpow(s,mod-2);
    27         g[0]=1;
    28         for(int k=1;k<(i>>1);k++)g[k]=(ll)g[k-1]*s%mod;
    29         for(int j=0;j<N;j+=i)
    30             for(int k=0;k<(i>>1);k++){
    31                 int x=a[j+k],y=(ll)a[j+k+(i>>1)]*g[k]%mod;
    32                 a[j+k]=Add(x,y),a[j+k+(i>>1)]=Dec(x,y);
    33             }
    34     }
    35     if (p){
    36         int s=qpow(N,mod-2);
    37         for(int i=0;i<N;i++)a[i]=(ll)a[i]*s%mod;
    38     }
    39 }
    40 int calc(){
    41     int ans=0;
    42     memset(A,0,sizeof(A));
    43     for(int i=1;i<n;i++)A[i]=(ll)a[i]*fac[n-i-1]%mod*fac[i+m-2]%mod;
    44     ntt(A);
    45     
    46     memset(B,0,sizeof(B));
    47     for(int i=1;i<min(n,m);i++)B[i]=(ll)mi[i]*inv[i-1]%mod*inv[m-i-1]%mod;
    48     ntt(B);
    49     for(int i=0;i<N;i++)B[i]=(ll)A[i]*B[i]%mod;
    50     ntt(B,1);
    51     for(int i=1;i<=n;i++)ans=(ans+4LL*B[i]*inv[n-i]%mod*inv[i-1])%mod;
    52     
    53     memset(B,0,sizeof(B));
    54     for(int i=1;i<min(n,m+1);i++)B[i]=(ll)mi[i]*inv[i-1]%mod*inv[m-i]%mod;
    55     ntt(B);
    56     for(int i=0;i<N;i++)B[i]=(ll)A[i]*B[i]%mod;
    57     ntt(B,1);
    58     for(int i=2;i<=n;i++)ans=(ans+(ll)B[i]*inv[n-i]%mod*inv[i-2])%mod;
    59     
    60     memset(B,0,sizeof(B));
    61     for(int i=1;i<min(n,m-1);i++)B[i]=(ll)mi[i]*inv[i-1]%mod*inv[m-i-2]%mod;
    62     ntt(B);
    63     for(int i=0;i<N;i++)B[i]=(ll)A[i]*B[i]%mod;
    64     ntt(B,1);
    65     for(int i=0;i<=n;i++)ans=(ans+3LL*B[i]*inv[n-i]%mod*inv[i])%mod;
    66     
    67     ans=4LL*(mod+1)/3*ans%mod;
    68     for(int x=1;x<=n;x++)ans=(ans+(ll)5*C(n-1,x-1)*C(m-1,x-1)%mod*a[n]%mod+mod)%mod;
    69     for(int x=2;x<=n;x++)ans=(ans+(ll)C(n-1,x-1)*C(m-1,x-2)%mod*a[n]%mod+mod)%mod;
    70     for(int x=1;x<=n;x++)ans=(ans+(ll)4*C(n-1,x-1)*C(m-1,x)%mod*a[n])%mod;
    71     return ans;
    72 }
    73 int main(){
    74     mi[0]=fac[0]=inv[0]=inv[1]=1;
    75     for(int i=1;i<N;i++)mi[i]=(ll)9*mi[i-1]%mod;
    76     for(int i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)+((i&1)*(N>>1));
    77     for(int i=1;i<N;i++)fac[i]=(ll)fac[i-1]*i%mod;
    78     for(int i=2;i<N;i++)inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
    79     for(int i=1;i<N;i++)inv[i]=(ll)inv[i-1]*inv[i]%mod;
    80     scanf("%d%d",&n,&m);
    81     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    82     ans=calc();
    83     for(int i=1;i<=m;i++)scanf("%d",&a[i]);
    84     swap(n,m),ans=(ans+calc())%mod;
    85     printf("%d\n",ans);
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    5.19 省选模拟赛 T1 小B的棋盘 双指针 性质
    5.15 省选模拟赛 容斥 生成函数 dp
    5.15 省选模拟赛 T1 点分治 FFT
    5.15 牛客挑战赛40 B 小V的序列 关于随机均摊分析 二进制
    luogu P4929 【模板】舞蹈链 DLX
    CF 878E Numbers on the blackboard 并查集 离线 贪心
    5.10 省选模拟赛 拍卖 博弈 dp
    5.12 省选模拟赛 T2 贪心 dp 搜索 差分
    5.10 省选模拟赛 tree 树形dp 逆元
    luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15606022.html
Copyright © 2011-2022 走看看