重排列(思维)

链接:https://ac.nowcoder.com/acm/contest/3007/D
来源:牛客网

题目描述

一个序列的重排列是指对这个序列中的元素进行若干次(包括0次)交换操作后得到的新序列
在本题中,序列中可能出现重复的数字,他们被视作不同的元素
例如,序列1 1的重排列有两种
现在有两个长度为 N 的非负整数序列 A 和 B,问有多少种 A 的重排列满足对于所有的 1≤i≤N,有A i≤B i
由于答案可能很大,你只需要输出答案对1e9+7取模的结果
 

输入描述:

输入第一行,包含一个正整数 N
接下来一行,N 个非负整数表示序列 A
再接下来一行,N 个非负整数表示序列 B
1≤N≤100,000,0≤A i,B i≤10 9

输出描述:

一行一个整数,表示答案

输入

4
1 1 2 3
1 2 3 4

输出

8

官方题解:

容易知道按升序将A和B排序不影响结果。
按标号从小到大考虑A的每个位置填什么数。
例:A(1,2,3)
  B(1,3,4)
则考虑第一个位置时,只能填1。
考虑第二个位置时,可以填2或3。
但是由于2和3在这里是完全等价的,也就是说我们并不关心填了谁。
那么我们只需要记录每一步有多少个数可填就好了,这个答案与之前填入的方案无关。
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <string>
 5 #include <math.h>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <stack>
 9 #include <queue>
10 #include <set>
11 #include <map>
12 #include <sstream>
13 const int INF=0x3f3f3f3f;
14 typedef long long LL;
15 const double eps =1e-8;
16 const int mod=1e9+7;
17 const int maxn=1e6+10;
18 using namespace std;
19 
20 int a[100005];
21 int b[100005];
22 
23 int main()
24 {
25     #ifdef DEBUG
26     freopen("sample.txt","r",stdin);
27     #endif
28     
29     int n;
30     scanf("%d",&n);
31     for(int i=1;i<=n;i++)
32         scanf("%d",&a[i]);
33     for(int i=1;i<=n;i++)
34         scanf("%d",&b[i]);
35     sort(a+1,a+1+n);
36     sort(b+1,b+1+n);
37     LL ans=1;
38     for(int i=1;i<=n;i++)
39     {
40         int pos=upper_bound(a+1,a+1+n,b[i])-(a+1)+1-1;//在a中寻找第一个大于b[i]的位置 
41         int num=pos-i+1;//从i开始小于等于b[i]的个数 
42         ans=ans*num%mod;
43     }
44     printf("%lld\n",ans);
45     
46     return 0;
47 }

官方给的是用双指针进行一轮扫描,因为sort了,好像更好一点,贴出来吧

 1 作者:珩月
 2 链接:https://ac.nowcoder.com/discuss/367149?type=101&order=0&pos=6&page=0
 3 来源:牛客网
 4 
 5 #include <iostream>
 6 #include <cstdio>
 7 #include <cstring>
 8 #include <algorithm>
 9 #include <cmath>
10  
11 using namespace std;
12 typedef long long LL;
13 const int N = 100050;
14 const LL mod = 1000000007;
15  
16 int a[N], b[N], ans = 1, n; 
17 int main()
18 {
19      
20     int i, j, k;
21     cin >> n;
22     for(i = 1; i <= n; i ++)
23         scanf("%d", &a[i]);
24     for(i = 1; i <= n; i ++)
25         scanf("%d", &b[i]);
26     sort(a + 1, a + n + 1);
27     sort(b + 1, b + n + 1);
28     for(i = 1, j = 0; i <= n; i ++){
29         while(j < n && a[j + 1] <= b[i])
30             j ++;
31         ans = (LL)ans * max(0ll, j - i + 1ll) % mod;
32     }
33     printf("%d", (ans + mod) % mod);
34      
35     return 0;
36 }

-

猜你喜欢

转载自www.cnblogs.com/jiamian/p/12319314.html