题目连接:hdu_5719_Arrange
题意:
给你1-n这 n个数,设一个排列的第i个数为Ai, Bi为A1到Ai的最小值,Ci为C1到Ci的最大值,问你有多少种排列方式,然后输出取模后的答案
题解:
最开始没注意每个数只能用一次,操蛋!这个条件太隐藏了,我们从1到n位开始扫,并且维护一个区间还剩多少数没有用,然后用乘法计数就是最终的答案,注意一些导致答案为0的条件即可
1 #include<cstdio> 2 #define F(i,a,b) for(int i=a;i<=b;i++) 3 4 const int mod=998244353,N=1e5+7; 5 int a[N],b[N]; 6 7 int main(){ 8 int t,n; 9 scanf("%d",&t); 10 while(t--){ 11 scanf("%d",&n); 12 F(i,1,n)scanf("%d",a+i); 13 F(i,1,n)scanf("%d",b+i); 14 if(a[1]!=b[1])puts("0"); 15 else{ 16 int ma=a[1],mi=a[1],sq=0; 17 long long ans=1; 18 F(i,2,n){ 19 if(a[i]>b[i]){ans=0;break;} 20 if(a[i]>mi||b[i]<ma){ans=0;break;} 21 if(a[i]<mi&&b[i]>ma){ans=0;break;} 22 if(a[i]<mi){sq+=mi-a[i]-1,mi=a[i];continue;} 23 if(b[i]>ma){sq+=b[i]-ma-1,ma=b[i];continue;} 24 if(sq==0){ans=0;break;} 25 ans=ans*sq%mod,sq--; 26 } 27 printf("%lld ",ans); 28 } 29 } 30 return 0; 31 }