codeforcesB. Siga ta Kymata
题目
题目
https://codeforces.com/contest/2163/problem/B
思路
本题目关键在于题目理解
先看操作是如何进行的

这里首先需要注意的是只能修改(l,r)这一开区间内的si,且1<=l<=r<=n
- 因此也就是说s1和sn绝对不可能被设置成1,因此如果x1,xn如果有一个等于1,那就不符合条件输出-1
其次需要注意的是,pi的值要严格大于min(pl,pr),且严格小于max(pl,pr)
- 因此如果排列中最大数对应位置的x为1,排列中最小数对应位置的x为1,那就不符合条件输出-1
再看要求具体是什么

这里需要注意!!!无需使得s与x处处相同,只需使得xi为 1时对应si为1即可,xi为0时,si没有具体要求
然后在考虑其他情况
按平常做题的经验,这种操作次数没有强制要求取最小值最大值的题目,通常都是有一个固定操作次数能满足所有的情况,而且通常是所规定的最大操作次数,例如本题通过五次操作能使得除上述被否掉的情况外的所有操作满足条件
先列出操作在具体解释,假设在排列中1的位置是mn,n的位置是mx,且mn<mx
1-mn
1-mx
mn-mx
mn-n
mx-n
通过上述五个操作能使得s中全部数都变成1,也就能使得全部情况就符合要求
现在我来详细解释
先画一个图

首先选(mn,mx)这一区间很好理解,这一区间内全部数都满足要求,都能全部数变为1
现在我们就要考虑如何让1-mn,mx-n这两个区间内的数也全变成1
通过1-mn,1-mx能使得1-mn这一区间的数全变为1
- 1-mn
min(pl,pr)=pr,max(pl,pr)=pl
这一区间的数绝对都满足严格大于min(pl,pr),所以严格小于max(pl,pr)的数都会变为1
- 1-mx
min(pl,pr)=pl,max(pl,pr)=pr
这一区间的数绝对都满足严格小于max(pl,pr),所以严格大于min(pl,pr)的数都会变为1
综上两个操作,1-mn这一区间就全为1了
通过mn-n,mx-n能使得mx-n这一区间的数全变为1
- mn-n
min(pl,pr)=pl,max(pl,pr)=pr
这一区间的数绝对都满足严格大于min(pl,pr),所以严格小于max(pl,pr)的数都会变为1
- mx-n
min(pl,pr)=pr,max(pl,pr)=pl
这一区间的数绝对都满足严格小于max(pl,pr),所以严格大于min(pl,pr)的数都会变为1
综上两个操作,mx-n这一区间就全为1了
综上五个操作s中全部数就都变成1了
这里需要注意一下,因为mn不一定在mx前面,所以mn-mx这一操作的具体l,
r为l=min(mn,mx)r=max(mn,mx)
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
// priority_queue<int, vector<int>, greater<int> > q;
const int N = 2e5+10;
const int inf=1e9;
int p[N];
void solve() {int n;cin >> n;int mn=n+1,mx=0;for (int i=0;i<n;i++) {cin >> p[i];if (p[i]==n)mx=i;if (p[i]==1)mn=i;}string s;cin >> s;if (s[0]=='1'||s[n-1]=='1'||s[mx]=='1'||s[mn]=='1') {cout << -1 << endl;return ;}cout << 5 << endl;cout << 1 << " " << mn+1 << endl;//我下标是从0开始算的,所以这里都需要+1cout << 1 << " " << mx+1 << endl;cout << mn+1 << " " << n << endl;cout << mx+1 << " " << n << endl;cout << 1 << " " << n << endl;// vector<pair<int,int> >a;// int pd=0,zb=0;// for (int i=0;i<=n-1;i++) {// pd=0;// while (s[i]=='1') {// if (!pd)zb=i,pd=1;// i++;// }// a.push_back({zb,i-1});// }}signed main() {int q;cin >> q;while (q--) {solve();}return 0;
}
