• BZOJ4584 APIO2016赛艇(动态规划+组合数学)


      如果值域不大,容易想到设f[i][j]为第i个学校选了j的方案数,枚举上一个学校是哪个选了啥即可,可以前缀和优化。于是考虑离散化,由于离散化后相同的数可能可以取不同的值,所以枚举第一个和其所选数(离散化后)相同的学校是哪个,考虑这一段里选几个学校怎么选数,组合数即可。各种显然的优化后即可做到O(n3),瞎卡卡常就……根本过不了。被卡常已经习惯了。不要把有限的生命投入无限的卡常之中。越菜的人越容易被卡常。——沃兹基硕德。luogu8s,darkbzoj40s,bzoj?s。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 510
    #define P 1000000007
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int n,a[N],b[N],f[N][N<<2],g[N][N<<2],C[N][N],c[N],h[N<<2][N],u[N<<2],v[N<<2],l[N<<2],r[N<<2],last[N][N<<2],tot[N<<2],t;
    void inc(int &x,int y){x+=y;if (x>=P) x-=P;}
    int inv(int a)
    {
        int s=1,k=P-2;
        for (;k;k>>=1,a=1ll*a*a%P) if (k&1) s=1ll*s*a%P;
        return s;
    }
    void pre()
    {
        sort(v+1,v+t+1);
        t=unique(v+1,v+t+1)-v-1;int t2=0;
        u[++t2]=v[1];l[t2]=r[t2]=v[1];
        for (int i=2;i<=t;i++)
        {
            if (v[i]-1!=v[i-1]) u[++t2]=v[i]-1,l[t2]=v[i-1]+1,r[t2]=v[i]-1;
            u[++t2]=v[i],l[t2]=v[i],r[t2]=v[i];
        }
        t=t2;memcpy(v,u,sizeof(v));
        for (int i=1;i<=n;i++) a[i]=lower_bound(v+1,v+t+1,a[i])-v,b[i]=lower_bound(v+1,v+t+1,b[i])-v;
        for (int i=1;i<=t;i++)
        {
            int l=0;
            for (int j=1;j<=n;j++)
            if (a[j]<=i&&i<=b[j]) last[j][i]=l,tot[i]++,l=j;
            else last[j][i]=0;
        }
    }
    void calc()
    {
        C[0][0]=1;
        for (int i=1;i<=n;i++)
        {
            C[i][0]=C[i][i]=1;
            for (int j=1;j<i;j++) C[i][j]=(C[i-1][j-1]+C[i-1][j])%P;
        }
        for (int i=1;i<=t;i++)
        {
            memset(c,0,sizeof(c));
            c[0]=1;
            for (int j=1;j<=n&&j<=r[i]-l[i]+2;j++)
            c[j]=1ll*c[j-1]*(r[i]-l[i]+1-j+1)%P*inv(j)%P;
            for (int j=2;j<=tot[i];j++)
                for (int p=2;p<=j;p++)
                inc(h[i][j],1ll*C[j-2][p-2]*c[p]%P);
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj4584.in","r",stdin);
        freopen("bzoj4584.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read();
        for (int i=1;i<=n;i++) v[++t]=a[i]=read(),v[++t]=b[i]=read();
        pre();calc();
        f[0][0]=1;for (int i=0;i<=t;i++) g[0][i]=1;
        for (int i=1;i<=n;i++)
        {
            for (int j=a[i];j<=b[i];j++)
            {
                f[i][j]=1ll*g[i-1][j-1]*(r[j]-l[j]+1)%P;
                int cnt=1;
                for (int k=last[i][j];k;k=last[k][j])
                inc(f[i][j],1ll*g[k-1][j-1]*h[j][++cnt]%P);
            }
            for (int j=1;j<=t;j++) g[i][j]=(g[i][j-1]+f[i][j])%P;
            for (int j=0;j<=t;j++) inc(g[i][j],g[i-1][j]);
        }
        cout<<(g[n][t]+P-1)%P;
        return 0;
    }
  • 相关阅读:
    Qt: 自动调整到最合适的大小(不是很明白)
    Qt: 读写二进制文件(写对象, 原始数据等)
    Qt: 把内容写进字符串中与C++很相似(使用QTextStream包装QString)
    2008技术内幕:T-SQL语言基础
    bootstrap + angularjs + seajs构建Web Form前端2
    SignalR 2.0 系列: SignalR简介
    Amazon前技术副总裁解剖完美技术面试
    MongoDB数据文件内部结构
    SQL Server三种表连接原理
    了解mongoDB存储结构
  • 原文地址:https://www.cnblogs.com/Gloid/p/9899298.html
Copyright © 2020-2023  润新知