传送门
题意:给一个长度为nnn的只有111和222的序列,多次询问给定xxx构造或判断无法构造一个区间和为xxx
注意到111和222实质上是改不改变奇偶性,所以往这上面考虑
我们发现如果一个区间[L,R][L,R][L,R]和为x(x>2)x(x>2)x(x>2),我们就可以构造出x−2x-2x−2。方法是如果端点有222把这个222去掉,否则两边都是111,把两边都去掉。
也就是说,如果xxx可以构造,那么小于xxx的奇偶性相同的正整数都可以构造出。
那我们只需要对奇数和偶数分别找出最大的即可。
显然[1,n][1,n][1,n]是其中一个。
然后找到离端点最近的111,整体挖掉就可以改变奇偶性,显然是最大的。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#define MAXN 2000005
using namespace std;
int l[MAXN],r[MAXN];
char s[MAXN];
int a[MAXN];
int main()
{int n,m;scanf("%d%d",&n,&m);scanf("%s",s+1);int sum=0;for (int i=1;i<=n;i++) sum+=(a[i]=1+(s[i]=='T'));l[sum]=1,r[sum]=n;int k1=0,k2=0;while (a[k1+1]==2) ++k1;while (a[n-k2]==2) ++k2;if (k1<n-1||k2<n-1){if (k1<k2) l[sum-2*k1-1]=k1+2,r[sum-2*k1-1]=n;else l[sum-2*k2-1]=1,r[sum-2*k2-1]=n-k2-1; }for (int i=sum;i>=3;i--){if (!l[i]) continue;if (a[l[i]]==2) l[i-2]=l[i]+1,r[i-2]=r[i];elseif (a[r[i]]==2) l[i-2]=l[i],r[i-2]=r[i]-1;else l[i-2]=l[i]+1,r[i-2]=r[i]-1;}while (m--){int x;scanf("%d",&x);if (!l[x]) puts("NIE");else printf("%d %d\n",l[x],r[x]);}return 0;
}