首页 > 其他分享 >JOISC2020

JOISC2020

时间:2024-03-05 11:11:06浏览次数:23  
标签:notin int 位置 JOISC2020 leq getchar

[JOISC2020] 最古の遺跡 3

好难的题。

首先考虑给出 \(h\) 怎么求 \(A\) ,设 \(h'_i\) 为 \(i\) 位置剩下的高度,没了就 \(=0\)。

方便起见,我们把原序列翻转一下,那么题目的操作就是,每种高度的最靠左的位置不变。

我们从左到右依次求解,先令 \(h'_i=h_i\),若 \(h'_i\) 在 \(j<i\) 的 \(h'_j\) 中出现过,那么 \(h'_i\) 一定会被震低,让 \(h'_i-1\) 继续判断即可。直到没出现过或者 \(h'_i=0\) 。

设 \(H\) 为最大的,满足 \(1\to H\) 的高度在前 \(i-1\) 的 \(h'\) 中都出现的 \(H\) ,那么 \(i\) 位置被保留当且仅当 \(H< h_i\) 。

设 \(dp_{i,j}\) 为考虑到了第 \(i\) 个位置, \(H=j\) 的方案数。

  • 若 \(i\notin A\),则 \(h_i\leq H\),\(h_i\) 一共有 \(H-c_0\) 种取法,其中 \(c_0\) 为 \(j\notin A,j<i\) 的 \(j\) 个数,注意此求法相当于给同一种高度的两个数加以区分了,所以最后要除以 \(2^n\) 。

  • 若 \(i\in A\),则 \(h_i>H\) ,但是 \(h_i\) 不一定会影响到 \(H\),这是不好算的,我们考虑在 \(H\) 改变时一起计算,因此:

    • 加入该位置不改变 \(H\),我们把该位置的贡献延后计算。
    • 加入该位置改变了 \(H\),容易发现此时一共有 \(c_1-H\) 个位置被延后计算了,其中 \(c_1\) 为 \(j\in A,j<i\) 的 \(j\) 个数。那么我们枚举新的 \(H=k\),那么因为 \(i\) 是第一个改变了 \(H\) 的位置,所以 \(h'_i=j+1\),那么 \(h_i\) 的取值一共有 \((k-j-1)+2\),其中 \(k-j-1\) 是因为这些数在被延后计算的数占用过了,\(+2\) 是因为 \(j+1\) 必定没有被用过。然后还要选出剩下的 \(k-j-1\) 个被延后计算的位置,那就是 \(\binom{c_1-j}{k-j-1}\),最后还要进行给这 \(k-j-1\) 个数填数,也就是:用 \(j+2\to k\) 这些数字给 \(k-j-1\) 个位置填数,满足他们的 \(h'\) 恰好构成 \(j+2\to k\) 的方案数,我们记为 \(g_{k-j-1}\) 。

\(g_n\) 的求法,显然充要条件是对于任意 \(1\leq i\leq n\),最多有 \(i\) 个位置填的数 \(\leq i\) ,那么我们记 \(t_{i,j}\) 表示填到 \(i\),填了 \(j\) 个位置的方案数,转移是简单的。

复杂度 \(O(n^3)\)

#include<bits/stdc++.h>
using namespace std;
const int N = 1202;
const int mod = 1e9+7;
int n;
bool key[N];
template <typename T>inline void read(T &x)
{
    x=0;char c=getchar();bool f=0;
    for(;c<'0'||c>'9';c=getchar())f|=(c=='-');
    for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+(c^48);
    x=(f?-x:x);
}
int binom[N][N],g[N],t[N][N];
int dp[N][N];
const int inv2=(mod+1)/2;
int main()
{
    read(n);
    int m=n*2;
    for(int i=1;i<=n;i++)
    {
        int x;
        read(x);
        x=m-x+1;
        key[x]=1;
    }
    binom[0][0]=1;
    for(int i=1;i<=m;i++)
    {
        binom[i][0]=1;
        for(int j=1;j<=i;j++)
        binom[i][j]=(binom[i-1][j-1]+binom[i-1][j])%mod;
    }
    g[0]=1;
    for(int L=1;L<=n;L++)
    {
        for(int i=0;i<=L;i++)
        for(int j=0;j<=L;j++)
        t[i][j]=0;
        t[0][0]=1;
        for(int i=1;i<=L;i++)
        for(int j=0;j<=i-1;j++)
        if(t[i-1][j])
        {
            t[i][j]=(t[i][j]+t[i-1][j])%mod;
            t[i][j+1]=(t[i][j+1]+2ll*(L-j)*t[i-1][j]%mod)%mod;
            t[i][j+2]=(t[i][j+2]+1ll*(L-j)*(L-j-1)%mod*t[i-1][j]%mod)%mod;
        }
        g[L]=t[L][L];
    }
    dp[0][0]=1;
    int c0=0,c1=0;
    for(int i=1;i<=m;i++)
    {
        if(!key[i])
        {
            for(int j=0;j<=n;j++)
            if(dp[i-1][j])dp[i][j]=1ll*dp[i-1][j]*(2*j-c0-j)%mod;
            c0++;
        }
        else
        {
            for(int j=0;j<=n;j++)if(dp[i-1][j])
            {
                dp[i][j]=(dp[i][j]+dp[i-1][j])%mod;
                for(int k=j+1;k<=n;k++)
                dp[i][k]=(dp[i][k]+1ll*dp[i-1][j]*(k-j+1)%mod*binom[c1-j][k-j-1]%mod*g[k-j-1]%mod)%mod;
            }
            c1++;
        }
    }
    int ans=dp[m][n];
    for(int i=1;i<=n;i++)ans=1ll*ans*inv2%mod;
    cout<<ans;
    return 0;
}

标签:notin,int,位置,JOISC2020,leq,getchar
From: https://www.cnblogs.com/jesoyizexry/p/18053554

相关文章

  • [JOISC2020] 扫除
    现在Bitaro准备用扫帚打扫房间。我们认为扫帚是放置在房间里的一条线段,并且将这条线段的长度称为扫帚的宽度。由于Bitaro很有条理,所以他只会用以下的两种方式打扫房间:Bitaro将扫帚平行于\(y\)轴放置,一端位于原点。然后他会垂直向右移动扫帚,直到不能移动为止。如果扫帚的......
  • [JOISC2020] 最古の遺跡 3
    [JOISC2020]最古の遺跡3题目背景JOI教授是一名研究IOI王国的历史学家。题目描述他发现了一行古代石柱的废墟及一份古代文献。古代文献上的记载如下:刚建造完成的时候,有\(2\timesN\)个石柱,对于\(1\lek\leN\)均有两个石柱高度为\(k\),同时记第\(i\)个石柱的高度......
  • JOISC2020题解
    \(\text{ByDaiRuiChen007}\)ContestLinkA.Building4ProblemLink题目大意给\(2n\)个数对\((a_i,b_i)\),构造一个非降序列\(c_i\)满足\(\forall1\lei\len,c_i\in\{a_i,b_i\}\),且\(c_i=a_i\)的位置恰好有\(n\)个。数据范围:\(n\le5\times10^5\)。思路......
  • P6891 [JOISC2020] ビルの飾り付け 4
    P6891[JOISC2020]ビルの飾り付け4题目传送门Problem给定长度为\(2n\)(\(1\len\le5\times10^5\))的序列\(A\),\(B\)。要求构造一个单调不降的序列\(C\)。每个\(C_i\)从\(A_i\)和\(B_i\)中选取,且\(A\),\(B\)中都恰好选取\(n\)个。Solution最直接的想法显然是dp......
  • JOISC2020 Day2 T3 遗迹
    考虑给你\(h\),怎么整体得到最后的\(a\)这里感觉不能去想让一个位置\(x\)留下来的冲要条件,不然可能就做不出来了。自然的想法:从$2n$到\(1\)遍历每个\(h_i\),然后从\(h_i\)到\(1\)找第一个没有标记的值\(x\),此时\(i\)能留下来,如果找不到\(x\),那么\(i\)无法留下来......
  • P7213 [JOISC2020] 最古の遺跡 3 乱写
    不想写题解了,把写在草稿纸上的东西整理了一下感谢crashed大佬的题解与对本人问题的回答,没有他我就不会搞懂这道神仙计数题。......
  • 【JOISC2020】治疗计划
    【JOISC2020】治疗计划DescriptionJOI村庄有\(N\)个房屋,编号为\(1\)到\(N\),每个房屋住有一个村民,第\(i\)个房屋居住编号为村民\(i\)。现在,这\(N\)个房屋里的......
  • 「JOISC2020」扫除
    题目点这里看题目。分析观察一下部分分,前三个subtasks都比较简单。仔细思考一下,发现之后的难点都在于\(x,y\)两个坐标分离处理,这导致我们无法轻易地找出需要被修改......
  • luogu P7219 [JOISC2020] 星座 3
    题面传送门实在没东西写了,随便拉一道题凑数。首先看这个东西就感觉只和两个点有关,事实上也是这样。关于最大值的问题肯定要把笛卡尔树建立出来,然后最大值变成两个点的LC......