题目链接:Codeforces Round #631 (Div. 2) B. Dreamoon Likes Permutations
题意:给定整数数组a,将a分为两个数组p1、p2,使p1、p2同时满足条件:若数组长度为k,则数组中出现1~k的所有数。
解题思路:
1、将条件分解
长度为k的数组中出现1~k的所有数等价于:
①出现k个数 ②这k个数的和是1~k的和
2、
对条件①,用set容器保存当前出现的所有数,set.size( )即为不重复的数的个数。若到第k个数,set.size( ) == k,则条件①满足。(不用set容器也可以,只要能记录出现的不重复的数的个数就行)
对条件②,用一个变量sum在循环过程中记录1~k的和,再与数组第1个到第k个数字的和比较。若到第k个数,数组和 == sum,则条件②满足。
3、
在t点将a分为p1、p2,若p1、p2都满足条件①②,则t点是一个答案。
这个做法因为记录了前缀和,所以不能用int记录,不然会在第8个测试点出错。
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<string>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<utility>
using namespace std;
const long long INF = ~0ull>>2;
const int Inf = 0x3f3f3f3f;
const int maxn = 2e6+5;
bool flag[maxn];
int n;
vector<pair<int, int> > res;
/*node[i].cnt指直到位置i,一共出现了多少个不重复数
node[i].val指到i的前缀和*/
struct tagnode{
long long cnt, val;
}node[maxn];
void init()
{
fill(flag, flag+n+5, false);
res.clear();
node[0].val = 0;
return;
}
int main()
{
int T;
scanf("%d", &T);
while (T--){
scanf("%d", &n);
init();
set<int> kase;
long long sum = 0;
for (int i = 1; i <= n; i++){
sum += i;
long long a;
scanf("%lld", &a);
kase.insert(a);
node[i].val = node[i-1].val + a; //求前缀和
node[i].cnt = kase.size();
/*node[i].cnt == i 指满足条件①
node[i].val == sum 指满足条件②
两个条件都满足,则这个p1满足条件*/
if (node[i].cnt == i && node[i].val == sum)
flag[i] = true;
//flag[i] == true 指以i点为分割点,p1满足条件
}
/*要p1、p2都满足条件,还要考察p2*/
kase.clear();
sum = 0;
for (int i = n; i >= 1; i--){
//sum也是从1加到n
sum += n-i+1;
long long a = node[i].val - node[i-1].val;
long long sum_b = node[n].val - node[i-1].val;//后缀和
kase.insert(a);
/*kase.size() == n-i+1 指满足条件①
sum_b == sum 指满足条件②
两个条件都满足,则这个p2满足条件
flag[i-1] == true 指这个p2对应的p1满足条件
若p1、p2都满足条件,则分割点i是一个答案*/
if (kase.size() == n-i+1 && sum_b == sum && flag[i-1]){
pair<int, int> temp;
temp.first = i-1; //i-1是p1的长度
temp.second = n-i+1;//n-i+1是p2的长度
res.push_back(temp);
}
}
printf("%d\n", res.size());
for (int i = 0; i < res.size(); i++)
printf("%d %d\n", res[i].first, res[i].second);
}
return 0;
}