[XXI Open Cup,Grand Prix of Tokyo]Ascending Matrix

Posted StaroForgin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[XXI Open Cup,Grand Prix of Tokyo]Ascending Matrix相关的知识,希望对你有一定的参考价值。

Ascending Matrix

题解

首先,这道题是要求所有的数列是从上往下,从左往右,都是递增的。
首先从左往右递增,我们可以去考虑它的差分序列,每个点的值就是它前面差分序列的点数嘛。
从上往下递增,我们可以去考虑它差分序列的移动。
我们可以去考虑决定前面 ⩽ x \\leqslant x x,后面 > x >x >x的这个差分点。可以发现,从上往下,这个差分点是单调不左移的,它只会不断右移,并且不会超过下一个差分点。
那我们可以将原序列看成一个网格图,序列上每个数的位置就相当于网格图上的一个方格,每个差分点就是网格图上的一条竖着的边。将竖着的边连在一起,也就构成了网格图上的一条路径。
可以发现,这些路径都是互不跨越的,因为上一个差分点不会超过下一个差分点。
如果我们把左上的顶点看成 ( 1 , 1 ) (1,1) (1,1),右下的顶点看成 ( n + 1 , m + 1 ) (n+1,m+1) (n+1,m+1),那么所有的路径都是从 ( n + 1 , 1 ) (n+1,1) (n+1,1) ( 1 , m + 1 ) (1,m+1) (1,m+1)的。

但如果只是互不跨越的路径的话不好计数呀,我们可以手动将每条路径平移一下,将第 i i i条路径的起点平移到 ( n + i + 1 , i + 1 ) (n+i+1,i+1) (n+i+1,i+1),终点平移到 ( i + 1 , m + i + 1 ) (i+1,m+i+1) (i+1,m+i+1)
这样的话,原来互不跨越的条件就被转移成了互不相交,显然,我们这个网格图是有向无环图,这不可以 L G V \\rm LGV LGV引理?
但我们确定 ( r , c ) (r,c) (r,c)上的数为 V V V的条件是怎么处理的呢?
我们看看这个条件在网格图上说明了什么,显然,这个格点前面得有恰好 V − 1 V-1 V1条路径。
这也就是说明,原图中要有 V − 1 V-1 V1条路径与直线 x − y + c − r = 0 x-y+c-r=0 xy+cr=0的交点必须在 ( r + 1 , c + 1 ) (r+1,c+1) (r+1,c+1)的严格左上方,有 K − V K-V KV条路径的交点得在 ( r + 1 , c + 1 ) (r+1,c+1) (r+1,c+1)的非严格右下方。
平移后的图也就是说要 V − 1 V-1 V1条路径在 ( r + V , c + V ) (r+V,c+V) (r+V,c+V)的严格左上方, K − V K-V KV条路径要在 ( r + V , c + V ) (r+V,c+V) (r+V,c+V)的严格右下方。
其中 ( r + V , c + V ) (r+V,c+V) (r+V,c+V)是相对于第 V − 1 V-1 V1条路径平移得到的,显然,当且仅当第 V − 1 V-1 V1条路径满足条件时,恰好有 V − 1 V-1 V1条路径在左上方。而对于后面 K − V K-V KV条路径,它们的条件也是当且仅当第 V V V条路径满足条件是满足,而第 V V V条路径比第 V − 1 V-1 V1条路径多移动一步,所以就变成了严格右下方。

考虑有了上面的条件我们怎么建立矩阵,由于 L G V \\rm LGV LGV引理为了容斥是要求线段之间地位平等的,所以不可能每条起点直接算合法路径。但我们可以用一个经典的技巧,对于左上方的点,给它乘上一个 x x x的形式变量。
这样的话,我们矩阵上的每个点都是一个一次多项式,我们的行列式也就是一个 K − 1 K-1 K1次多项式。其中第 i i i项的系数表示有 i i i条路径在左上方的方案数。
我们可以考虑插值把这个多项式插出来,毕竟直接解也太麻烦了。

时间复杂度 O ( k 2 ( n + m ) + k 4 ) O\\left(k^2(n+m)+k^4\\right) O(k2(n+m)+k4)

源码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> pii;
#define MAXN 100005
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
#define lowbit(x) (x&-x)
const int mo=998244353;
const int inv2=5e8+4;
const int jzm=2333;
const int zero=200000;
const int INF=0x3f3f3f3f;
const double eps=1e-12;
const int orG=3,ivG=332748118;
template<typename _T>
_T Fabs(_T x)return x<0?-x:x;
template<typename _T>
void read(_T &x)
    _T f=1;x=0;char s=getchar();
    while(s<'0'||s>'9')if(s=='-')f=-1;s=getchar();
    while('0'<=s&&s<='9')x=(x<<3)+(x<<1)+(s^48);s=getchar();
    x*=f;

int add(int x,int y,int p)return x+y<p?x+y:x+y-p;
void Add(int &x,int y,int p)x=add(x,y,p);
int qkpow(int a,int s,int p)int t=1;while(s)if(s&1)t=1ll*a*t%p;a=1ll*a*a%p;s>>=1;return t;
int n,m,K,r,c,V,fac[1005],inv[1005],ff[1005];
int F[105][105][2];
struct poly
    int c[105];poly()
    void clear()for(int i=0;i<K;i++)c[i]=0;
    int ask(int x)
        int res=0,now=1;
        for(int i=0;i<K;now=1ll*x*now%mo,i++)
            Add(res,1ll*now*c[i]%mo,mo);
        return res;
    
    poly operator + (poly rhs)
        poly res;res.clear();
        for(int i=0;i<K;i++)
            res.c[i]=add(c[i],rhs.c[i],mo);
        return res;
    
    poly operator * (const int rhs)const
        poly res;res.clear();
        for(int i=0;i<K;i++)
            res.c[i]=1ll*rhs*c[i]%mo;
        return res;
    
    poly operator ^ (const int rhs)const
        poly res;res.clear();
        for(int i=0;i<K;i++)res.c[i+1]=c[i];
        for(int i=0;i<K;i++)Add(res.c[i],mo-1ll*rhs*c[i]%mo,mo);
        return res;
    
A,B;
struct matrix
    int c[105][105];matrix()
    int sakura()
        int res=1;
        for(int i=1;i<K;i++)
            int k=i;for(int j=i;j<K;j++)if(c[j][i])k=j;break;
            if(k^i)res=mo-res;for(int j=i;j<K;j++)swap(c[k][j],c[i][j]);
            if(!c[i][i])return 0;int tmp=qkpow(c[i][i],mo-2,mo);
            for(int j=i+1;j<K;j++)if(c[j][i])
                int tp=1ll*c[j][i]*tmp%mo;
                for(int l=i;l<K;l++)
                    Add(c[j][l],mo-1ll*tp*c[i][l]%mo,mo);
            
        
        for(int i=1;i<K;i++)res=1ll*c[i][i]*res%mo;
        return res;
    以上是关于[XXI Open Cup,Grand Prix of Tokyo]Ascending Matrix的主要内容,如果未能解决你的问题,请参考以下文章

[XXI Open Cup,Grand Prix of Tokyo]Ascending Matrix

2019-2020 XX Open Cup, Grand Prix of Korea

XX Open Cup, Grand Prix of Tokyo

2015-2016 XVI Open Cup, Grand Prix of Bashkortostan, SKB Kontur Cup Stage 2

XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Peterhof.

XVII Open Cup named after E.V. Pankratiev. Eastern Grand Prix. Problem F. Buddy Numbers 贪心数论构造