• [loj3394]Tour


    考虑$a_{i}\ge 0$的情况,维护可重集$S=\{a_{i}\}$,从前往后依次确定$a_{i}$

    令$x,y$分别为$S$中的最小和最大值,取$a_{i}=\begin{cases}x&xy\le w\\y&xy>w\end{cases}$并在$S$中删除

    记$Y=\{i\mid a_{i}=y\}$,则$a_{i}a_{j}>w$(其中$i<j$)当且仅当$i\in Y$

    在此基础上,从前往后依次将$a_{i}$插入排列,限制即不与已加入的$Y$中元素相邻

    显然两个$Y$中元素不会相邻,则$a_{i}$有$i-2\sum_{j\in Y}[j\le i]$种插入方式,并对所有$i$累乘即可

    考虑$\exist a_{i}<0$的情况,记$A/B_{x}$分别表示$a_{i}\ge 0/<0$的元素段数恰为$x$​的方案数,则答案即
    $$
    \sum_{x=1}^{n}\left(2(x!)^{2}A_{x}B_{x}+(x-1)!x!A_{x}B_{x-1}+(x-1)!x!A_{x-1}B_{x}\right)
    $$
    根据对称性,不妨仅考虑$A_{x}$,即每个$a_{i}$的插入方式变为$(i-1)+x-2\sum_{j\in Y}[j\le i]$

    记以此法求出的答案为$A'_{x}$,并对空段的情况容斥,即$A_{x}=\sum_{i=0}^{x}(-1)^{x-i}{x\choose i}A'_{i}$

    注意到$A'_{x}$即是形如$\prod_{i=1}^{n}(x+z_{i})$的$n$个点值,分治FFT展开后多点求值即可

    上述做法可能被卡常,下面给出一个常数较小的做法:

    记$\Delta^{i}f(x)=\begin{cases}f(x)&i=0\\\Delta^{i-1}f(x+1)-\Delta^{i-1}f(x)&i\ge 1\end{cases}$,则$\Delta^{i}f(0)=\sum_{x=0}^{i}(-1)^{i-x}{i\choose x}f(x)$

    当$f(x)$为下降幂多项式时,注意到$(x+1)^{\underline{n}}-x^{\underline{n}}=nx^{\underline{n-1}}$,则$\Delta^{i}f(0)=i!\cdot [x^{\underline{i}}]f(x)$

    换言之,取$f(x)=\prod_{i=1}^{n}(x+z_{i})$,则$A_{x}=\Delta^{x}f(0)$,问题即求$f(x)$的下降幂的形式

    使用分治FFT,并以下降幂多项式的形式存储结果,问题即将两个下降幂多项式相乘

    考虑插$[0,n]$的点值,注意到$f(i)=i!\sum_{j=0}^{i}\frac{[x^{\underline{j}}]f(x)}{(i-j)!}$,逆过程即$[x^{\underline{i}}]f(x)=\sum_{j=0}^{i}\frac{(-1)^{i-j}j!f(j)}{(i-j)!}$

    预处理$e^{x}$和$e^{-x}$的$DFT$结果,分治时从多项式取模$\rightarrow 6$次$DFT$

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

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 600005
      4 #define mod 998244353
      5 #define ll long long
      6 #define vi vector<int>
      7 #define mid (l+r>>1)
      8 int n,m,w,x,ans,fac[N],inv[N],rev[N],W[20][N][2];
      9 vi ex[20],Ex[20],a,b,v,A,B;
     10 int qpow(int n,int m){
     11     int s=n,ans=1;
     12     while (m){
     13         if (m&1)ans=(ll)ans*s%mod;
     14         s=(ll)s*s%mod,m>>=1;
     15     }
     16     return ans;
     17 }
     18 void init(int n){
     19     m=0;
     20     while ((1<<m)<n)m++;
     21     for(int i=0;i<(1<<m);i++)rev[i]=(rev[i>>1]>>1)+((i&1)<<m-1);
     22 }
     23 void ntt(vi &a,int p=0){
     24     for(int i=0;i<(1<<m);i++)
     25         if (i<rev[i])swap(a[i],a[rev[i]]);
     26     for(int i=2,t=0;i<=(1<<m);i<<=1,t++)
     27         for(int j=0;j<(1<<m);j+=i)
     28             for(int k=0;k<(i>>1);k++){
     29                 int x=a[j+k],y=(ll)W[t][k][p]*a[j+k+(i>>1)]%mod;
     30                 a[j+k]=x+y;if (a[j+k]>=mod)a[j+k]-=mod;
     31                 a[j+k+(i>>1)]=x-y;if (a[j+k+(i>>1)]<0)a[j+k+(i>>1)]+=mod; 
     32             }
     33     if (p){
     34         int s=qpow((1<<m),mod-2);
     35         for(int i=0;i<(1<<m);i++)a[i]=(ll)a[i]*s%mod;
     36     }
     37 }
     38 vi calc(int l,int r){
     39     if (l==r)return vi{v[l],1};
     40     vi v,vl=calc(l,mid),vr=calc(mid+1,r);
     41     init((r-l<<1)+3),v.resize(1<<m),vl.resize(1<<m),vr.resize(1<<m);
     42     ntt(vl),ntt(vr);
     43     for(int i=0;i<(1<<m);i++){
     44         vl[i]=(ll)vl[i]*ex[m][i]%mod;
     45         vr[i]=(ll)vr[i]*ex[m][i]%mod; 
     46     }
     47     ntt(vl,1),ntt(vr,1);
     48     for(int i=0;i<=r-l+1;i++)v[i]=(ll)vl[i]*vr[i]%mod*fac[i]%mod;
     49     ntt(v);
     50     for(int i=0;i<(1<<m);i++)v[i]=(ll)v[i]*Ex[m][i]%mod;
     51     ntt(v,1),v.resize(r-l+2);
     52     return v;
     53 }
     54 vi calc(vi a){
     55     int n=a.size(),l=0,r=n-1;
     56     if (!n)return vi{1};
     57     v.resize(n),sort(a.begin(),a.end());
     58     for(int i=0;i<n;i++){
     59         v[i]=(i-(n-r-1<<1)+mod)%mod;
     60         if ((ll)a[l]*a[r]<=w)l++;else r--;
     61     }
     62     v=calc(0,n-1);
     63     for(int i=0;i<=n;i++)v[i]=(ll)v[i]*fac[i]%mod;
     64     return v;
     65 }
     66 int main(){
     67     fac[0]=inv[0]=inv[1]=1;
     68     for(int i=1;i<N;i++)fac[i]=(ll)fac[i-1]*i%mod;
     69     for(int i=2;i<N;i++)inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
     70     for(int i=1;i<N;i++)inv[i]=(ll)inv[i-1]*inv[i]%mod;
     71     for(int i=0;i<20;i++){
     72         W[i][0][0]=W[i][0][1]=1;
     73         W[i][1][0]=qpow(3,(mod-1>>i+1));
     74         W[i][1][1]=qpow(W[i][1][0],mod-2);
     75         for(int j=2;j<(1<<i);j++){
     76             W[i][j][0]=(ll)W[i][j-1][0]*W[i][1][0]%mod;
     77             W[i][j][1]=(ll)W[i][j-1][1]*W[i][1][1]%mod;
     78         }
     79     }
     80     for(int i=1;i<20;i++){
     81         init(1<<i),ex[i].resize(1<<i),Ex[i].resize(1<<i);
     82         for(int j=0;j<(1<<i-1);j++){
     83             ex[i][j]=inv[j];
     84             Ex[i][j]=(j&1 ? (mod-inv[j])%mod : inv[j]);
     85         }
     86         ntt(ex[i]),ntt(Ex[i]);
     87     }
     88     scanf("%d%d",&n,&w);
     89     for(int i=1;i<=n;i++){
     90         scanf("%d",&x);
     91         if (x>=0)a.push_back(x);
     92         else b.push_back(-x);
     93     }
     94     A=calc(a),B=calc(b);
     95     A.resize(n+1),B.resize(n+1);
     96     for(int i=1;i<=n;i++)
     97         ans=(ans+2LL*A[i]*B[i]+(ll)A[i]*B[i-1]+(ll)A[i-1]*B[i])%mod;
     98     printf("%d\n",ans);
     99     return 0;
    100 }
    View Code
  • 相关阅读:
    Discuz X3.2 分区 gid 完美伪静态方法 Apache/Nginx
    如何批量转换 WordPress 文章分类
    修改 WordPress 文件上传目录
    如何验证 jemalloc 优化 Nginx 是否生效
    .Net Core 1.1 + CentOs 7 环境配置
    DotNet Core中使用dapper
    爬虫 HttpHelper
    iTextSharp 不适用模板 代码拼接PDF
    .Net中的加密解密
    .Net Core使用 MiniProfiler 进行性能分析
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/16467922.html
Copyright © 2020-2023  润新知