HDU-5719 Arrange

Arrange

 
 Accepts: 221
 
 Submissions: 1401
 Time Limit: 8000/4000 MS (Java/Others)
 
 Memory Limit: 262144/262144 K (Java/Others)
问题描述
Cupid一不小心将爱情之箭射到了自己,他爱上了Psyche。

这引起了他的母亲Venus的注意。Venus将Psyche带到了一堆打乱的谷堆旁。

这儿共有nn堆稻谷,编号为11nn。Psyche需要将这些谷堆以某种顺序排列,设最终排在第ii位的谷堆是A_iAi。

她得知了一些该排列的要求:

  1. 对于任意整数i \in [1,n]i[1,n]A_1, A_2, ..., A_iA1,A2,...,Ai的最小值为B_iBi。

  2. 对于任意整数i \in [1,n]i[1,n]A_1, A_2, ..., A_iA1,A2,...,Ai的最大值为C_iCi。

现在Psyche想知道,共有多少种合法的排列。由于答案可能很大,输出时对998244353998244353取模。
输入描述
第一行,一个整数TT (1 \le T \le 15)(1T15),代表数据组数。

对于每组数据,第一行有一个整数nn (1 \le n \le 10 ^ 5)(1n105),代表排列大小。

第二行,nn个整数,第ii个整数为B_iBi (1 \le B_i \le n)(1Bin)。

第三行,nn个整数,第ii个整数为C_iCi (1 \le C_i \le n)(1Cin)
输出描述
输出TT行,对于每组数据输出答案对998244353998244353取模的结果。
输入样例
2
3
2 1 1
2 2 3
5
5 4 3 2 1
1 2 3 4 5
输出样例
1
0
Hint
对于第一组数据,只有一种合法的排列(2,1,3)(2,1,3)。

对于第二组数据,没有合法的排列。

解题思路:

这道题有很多的点需要小心

总体来说,就两个点,一个是判断有无解,一个是计算解的个数

求解解的个数就是直接类似全排列的方式求就行,这个并不难。主要是判断有无解。

无解的情况有:

1.b[0]和c[0]不相等

2.b[i]比c[i]大

3.b序列不是单调非升序

4.c序列不是单调非降序

5.在第i个位置时没有可以放在这个位置的元素


代码如下:

#include 
#include 
using namespace std;
#define mod 998244353
#define INF 0x3f3f3f3f
typedef long long LL;
const int maxn = 1e5 + 5;
int a[maxn], b[maxn];
int main()
{
    // freopen("test.in", "r+", stdin);
    // freopen("test.out", "w+", stdout);
    int t, n;
    scanf("%d", &t);
    while(t--){
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
        for(int i = 1; i <= n; ++i) scanf("%d", &b[i]);
        a[0] = INF; b[0] = -1;

        LL ans = 1;
        for(int i = 1; i <= n; ++i){
            if(i == 1 && a[i] != b[i]){
                ans = 0;
                break;
            }
            if(a[i] > a[i-1]) {
                ans = 0;
                break;
            }
            if(b[i] < b[i-1]){
                ans = 0;
                break;
            }
            if(b[i] < a[i]){
                ans = 0;
                break;
            }
            if(i != 1 && a[i] < a[i-1] && b[i] > b[i-1]){
                ans = 0;
                break;
            }

            if(a[i] == a[i-1] && b[i] == b[i-1]){
                if(b[i] - a[i] + 2 - i <= 0) {
                    ans = 0;
                    break;
                }
                ans = (ans * (b[i] - a[i] + 2 - i)) % mod;
            }
        }

        printf("%lld\n", ans);
    }
    return 0;
}


你可能感兴趣的:(HDU)