您的位置:首页 > 其它

BestCoder 2nd Anniversary/HDU 5719 姿势

2016-07-18 12:04 190 查看

Arrange

Accepts:221
Submissions:1401

TimeLimit:8000/4000MS(Java/Others)
MemoryLimit:262144/262144K(Java/Others)

问题描述
Cupid一不小心将爱情之箭射到了自己,他爱上了Psyche。

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

这儿共有n堆稻谷,编号为1到n。Psyche需要将这些谷堆以某种顺序排列,设最终排在第i位的谷堆是A​i​​。

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

1.对于任意整数i∈[1,n]A​1​​,A​2​​,...,A​i​​的最小值为Bi

2.对于任意整数i∈[1,n]A​1​​,A​2​​,...,A​i​​的最大值为Ci

现在Psyche想知道,共有多少种合法的排列。由于答案可能很大,输出时对998244353取模。

输入描述
第一行,一个整数T(1≤T≤15)代表数据组数。

对于每组数据,第一行有一个整数n(1≤n≤105),代表排列大小。

第二行,n个整数,第i个整数为BiB_iB​i​​(1≤Bi≤n)

第三行,n个整数,第i个整数为CiC_iC​i​​(1≤Ci≤n)

输出描述
输出T行,对于每组数据输出答案对998244353取模的结果。

输入样例
2
3
211
223
5
54321
12345

输出样例
1
0

Hint
对于第一组数据,只有一种合法的排列(2,1,3)

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

题意:中文题意长度为n的序列b[i]代表前i个数的最小值c[i]代表前i个数的最大值问有多少种合法的排列

题解:考虑只有当b[j]==b[j-1]&&c[j]==c[j-1])的时候才有贡献
但是注意1~n的数只能出现一次这就是gg的作用


#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<algorithm>
#definell__int64
#definemod1e9+7
#definePIacos(-1.0)
usingnamespacestd;
intt;
llb[100005];
llc[100005];
intn;
intmain()
{
while(scanf("%d",&t)!=EOF)
{
for(inti=1;i<=t;i++)
{
scanf("%d",&n);
for(intj=1;j<=n;j++)
scanf("%I64d",&b[j]);
for(intj=1;j<=n;j++)
scanf("%I64d",&c[j]);
if(b[1]!=c[1])
{
printf("0\n");
continue;
}
llans=1;
llm=1;
llgg=1;//注意
for(intj=2;j<=n;j++)
{
if(b[j]>b[j-1]||c[j]<c[j-1])
{
m=0;
continue;
}
else
{
if(b[j]!=b[j-1]&&c[j]!=c[j-1])
{
m=0;
continue;
}
else
{
if(b[j]!=b[j-1]||c[j]!=c[j-1])
gg++;
else
{
ans*=(c[j]-gg-b[j]+1);
gg++;
ans%=998244353;
}
}
}
}
if(m)
printf("%I64d\n",ans);
else
printf("0\n");
}
}
return0;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: