zoukankan      html  css  js  c++  java
  • loj#575. 「LibreOJ NOI Round #2」不等关系

    题目描述

    题解

    只想到 $n^2$ 的dp,然后优化不了qwq

    考虑容斥,考虑枚举一下有多少个位置的>是不合法的,其他的>的合法情况是未知的,那对答案的贡献就是 $(-1)^{cnt}$

    然后我们可以dp,设 $f_{i,j}$ 表示前 $i$ 段最多有 $j$ 个上升序列,于是我们列出dp式子 $f_{i,j}=sum_{k=0}^{i-1}f_{k,j-1}(_{s_i-s_k}^{n-s_k})$ ,由于容斥系数是 $±1$ ,所以dp其实没必要即第二维,即 $f_{i}=-sum_{k=0}^{i-1}f_{k}(_{s_i-s_k}^{n-s_k})$ ,然后式子拆开发现可以分治 $Ntt$ ,这里要注意<位置上的dp值设为 $0$ 即可

    效率: $O(nlog^2n)$

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=8e5+5,P=998244353;
    int n,A[N],B[N],t,p,f[N],c,G[2]={3,(P+1)/3},s,re[N],jc[N],ny[N];
    char ch[N];bool a[N];
    int X(int x){if (x>=P) x-=P;return x;}
    void pre(int l){
        for (t=1,p=0;t<l;t<<=1,p++);
        for (int i=0;i<t;i++)
            re[i]=(re[i>>1]>>1)|((i&1)<<(p-1));
    }
    int K(int x,int y){
        int A=1;
        for (;y;y>>=1,x=1ll*x*x%P)
            if (y&1) A=1ll*A*x%P;
        return A;
    }
    void Ntt(int *g,bool o){
        for (int i=0;i<t;i++)
            if (i<re[i]) swap(g[i],g[re[i]]);
        for (int wn,i=1;i<t;i<<=1){
            wn=K(G[o],(P-1)/(i<<1));
            for (int x,y,j=0;j<t;j+=(i<<1))
                for (int w=1,k=0;k<i;k++,w=1ll*w*wn%P)
                    x=g[j+k],y=1ll*w*g[i+j+k]%P,
                    g[j+k]=X(x+y),g[i+j+k]=X(x-y+P);
        }
        if (o)
            for (int i=0,v=K(t,P-2);i<t;i++)
                g[i]=1ll*v*g[i]%P;
    }
    void solve(int l,int r){
        if (l==r){
            if (l==0) f[l]=1;
            else if (!a[l]) f[l]=0;
            else f[l]=1ll*f[l]*(P-ny[n-l])%P;
            return;
        }
        int mid=(l+r)>>1;
        solve(l,mid);
        for (int i=l;i<=mid;i++)
            A[i-l]=1ll*f[i]*jc[n-i]%P;
        for (int i=0;i<=r-l+1;i++) B[i]=ny[i];
        pre(r-l+mid-l+3);Ntt(A,0);Ntt(B,0);
        for (int i=0;i<t;i++)
            A[i]=1ll*A[i]*B[i]%P;Ntt(A,1);
        for (int i=mid+1;i<=r;i++)
            f[i]=X(f[i]+A[i-l]);
        for (int i=0;i<t;i++) A[i]=B[i]=0;
        solve(mid+1,r);
    }
    int main(){
        scanf("%s",ch+1);n=strlen(ch+1)+1;
        for (int i=1;i<n;i++)
            a[i]=(ch[i]=='>'),c+=a[i];
        jc[0]=1;
        for (int i=1;i<=n;i++)
            jc[i]=1ll*i*jc[i-1]%P;
        ny[n]=K(jc[n],P-2);
        for (int i=n;i;i--)
            ny[i-1]=1ll*i*ny[i]%P;
        solve(0,n);
        for (int i=0;i<=n;i++) s=X(s+f[i]);
        if (c&1) s=X(P-s);
        cout<<s<<endl;return 0;
    }
  • 相关阅读:
    用 ArcMap 发布 ArcGIS Server FeatureServer Feature Access 服务 PostgreSQL 版本
    ArcMap 发布 ArcGIS Server OGC(WMSServer,MapServer)服务
    ArcScene 创建三维模型数据
    ArcMap 导入自定义样式Symbols
    ArcMap 导入 CGCS2000 线段数据
    ArcMap 导入 CGCS2000 点坐标数据
    ArcGis Server manager 忘记用户名和密码
    The view or its master was not found or no view engine supports the searched locations
    python小记(3)操作文件
    pytest(2) pytest与unittest的区别
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/12273846.html
Copyright © 2011-2022 走看看