The sequence of mm integers is called the permutation if it contains all integers from 11 to mm exactly once. The number mm is called the length of the permutation.
Dreamoon has two permutations p1p1 and p2p2 of non-zero lengths l1l1 and l2l2 .
Now Dreamoon concatenates these two permutations into another sequence aa of length l1+l2l1+l2 . First l1l1 elements of aa is the permutation p1p1 and next l2l2 elements of aa is the permutation p2p2 .
You are given the sequence aa , and you need to find two permutations p1p1 and p2p2 . If there are several possible ways to restore them, you should find all of them. (Note that it is also possible that there will be no ways.)
The first line contains an integer tt (1≤t≤100001≤t≤10000 ) denoting the number of test cases in the input.
Each test case contains two lines. The first line contains one integer nn (2≤n≤2000002≤n≤200000 ): the length of aa . The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤n−11≤ai≤n−1 ).
The total sum of nn is less than 200000200000 .
For each test case, the first line of output should contain one integer kk : the number of ways to divide aa into permutations p1p1 and p2p2 .
Each of the next kk lines should contain two integers l1l1 and l2l2 (1≤l1,l2≤n,l1+l2=n1≤l1,l2≤n,l1+l2=n ), denoting, that it is possible to divide aa into two permutations of length l1l1 and l2l2 (p1p1 is the first l1l1 elements of aa , and p2p2 is the last l2l2 elements of aa ). You can print solutions in any order.
6 5 1 4 3 2 1 6 2 4 1 3 2 1 4 2 1 1 3 4 1 3 3 1 12 2 1 3 4 5 6 7 8 9 1 10 2 3 1 1 1
2 1 4 4 1 1 4 2 0 0 1 2 10 0
wtcl,被细节坑到死==
思路比较好想,因为是全排列,所以这个数列最大的数肯定是较长的那个全排列的一端,所以两个全排列的长度分别为mmax和n-mmax,然后分别看1~mmax和mmax+1~n能否组成两个全排列,1~n-mmax和n-mmax+1~n能否组成两个全排列即可。
坑点1:有可能两个全排列完全一样,只需要输出一个即可。
坑点2:(主要是我脑残)0的阶乘是1,是合法的!所以输入
5
1 2 3 4 5
会输出:
2
0 5
5 0
#include <bits/stdc++.h> using namespace std; int n; int ori[200005]; bool ok(bool vis[],int n) { int cnt=0,i; for(i=1;i<=n;i++)if(!vis[i])return 0; return 1; } int main() { int t; cin>>t; while(t--) { cin>>n; int i; int mmax=0; for(i=1;i<=n;i++) { scanf("%d",&ori[i]); mmax=max(mmax,ori[i]); } bool vis1[200005]={0}; bool vis2[200005]={0}; int ans=0,l1=0,l2=0,l3=0,l4=0; for(i=1;i<=n-mmax;i++)vis1[ori[i]]=1; for(i=n-mmax+1;i<=n;i++)vis2[ori[i]]=1; if(ok(vis1,n-mmax)&&ok(vis2,mmax)) { ans++; l1=n-mmax,l2=mmax; } bool vis3[200005]={0}; bool vis4[200005]={0}; for(i=1;i<=mmax;i++)vis3[ori[i]]=1; for(i=mmax+1;i<=n;i++)vis4[ori[i]]=1; if(ok(vis3,mmax)&&ok(vis4,n-mmax)&&mmax*2!=n)//如果两个是一摸一样的全排列 只输出一个就行 { ans++; l3=mmax,l4=n-mmax; } cout<<ans<<endl; if(l1||l2)cout<<l1<<' '<<l2<<endl;//不能用&& 因为0!=1 有可能有0 5和5 0这种情况 if(l3||l4)cout<<l3<<' '<<l4<<endl; } return 0; }