Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 101 Accepted Submission(s): 41
Problem Description
Princess Arabella loves the letter `C`, which earned her the epithet `ArraBellaC`. She would like to endeavor to construct a periodic string with length n(n≤20000)to spare her tedious time. In every period of the string, the substring begins with dozens of `A`s and ends with dozens of `C`s, and dozens of `B`s are inserted between them, and the number of `A`, `B`, `C` is a, b, c.(For example, if a=1, b=1, c=2 then one of the period of the string is `ABCC`, and the periodic string is `ABCCABCC……`).Note that in the last period of the string, the substring can be incomplete and the last few letters of the period can be cut down.
And now, Arabella has constructed a periodic string, she want to give you a question: if she tells you the character is Ci(Ci∈{A,B,C}) in the Xi(Xi≤10000) , then could you tell her the value of a,b,c? If there are multiple answers, please find the lexicographically smallest answer. If you can’t find a valid answer, please print `NO`
Input
The first line gives an integer T(1≤T≤40) , which indicates the number of cases in the input.
The first line of every case contains only one integer m(1≤m≤5000), which means the number of characters AraBella told you.
A number Xi(1≤Xi≤10000) and a letter Ci are given in the following m lines, which means the position Xi in the string with letter Ci.
Output
Print a,b,c in order. If there are multiple answers, please find the lexicographically smallest answer. If you can’t find a valid answer, please print `NO`.(It is gratuated that 0
Sample Input
2 3 1 A 2 B 3 C 4 1 A 2 C 3 B 4 C
Sample Output
1 1 1 NO
题意:一个无限长的字符串,由一个叫periodic string的子串重复出现得到,如:子串为ABCC,则无限长字符串为ABCCABCC...。定义a b c为periodic string中ABC的数量。
现在给出m个字符出现的位置,问合法的情况下,字典序最小的a b c是多少,若没有合法情况,则输出NO。
题解:由于总长度只有1e4,可以枚举重复子串的长度,复杂度为O(nlogn),对于每个子串看做一块,每块内分别维护ABC的最左最右端点,根据题意可以知道,ABC的区间不能相交,否则就是不合法的,维护可以用RMQ。最后维护答案,选择abc字典序较小的即可。
#include
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define x first
#define y second
#define rep(i,a,b) for(int i=a;i=b;--i)
#define fuck(x) cout<<'['<<#x<<' '<<(x)<<']'
#define eps 1e-8
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector VI;
typedef pair PII;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fll;
const int MX = 1e4 + 5;
const int MM = 30;
int A[MX][MM], Bl[MX][MM], Br[MX][MM], C[MX][MM];
char ch[MX];
void ST(int n) {
rep(i, 0, n) {
A[i][0] = 0, Bl[i][0] = 2 * n, Br[i][0] = 0, C[i][0] = 2 * n;
if(ch[i] == 'A') A[i][0] = i;
if(ch[i] == 'B') Bl[i][0] = Br[i][0] = i;
if(ch[i] == 'C') C[i][0] = i;
}
for(int j = 1; (1 << j) <= n; j++) {
for(int i = 0; i + (1 << j) - 1 < n; i++) {
A[i][j] = max(A[i][j - 1], A[i + (1 << (j - 1))][j - 1]);
C[i][j] = min(C[i][j - 1], C[i + (1 << (j - 1))][j - 1]);
Bl[i][j] = min(Bl[i][j - 1], Bl[i + (1 << (j - 1))][j - 1]);
Br[i][j] = max(Br[i][j - 1], Br[i + (1 << (j - 1))][j - 1]);
}
}
}
int n;
int RMQ_min(int dp[][MM], int l, int r) {
int k = 0;
assert(0 <= l && l <= r && r < n);
while((1 << (k + 1)) <= r - l + 1) k++;
assert(r - (1 << k) + 1 >= 0);
return min(dp[l][k], dp[r - (1 << k) + 1][k]);
}
int RMQ_max(int dp[][MM], int l, int r) {
int k = 0;
assert(0 <= l && l <= r && r < n);
while((1 << (k + 1)) <= r - l + 1) k++;
assert(r - (1 << k) + 1 >= 0);
return max(dp[l][k], dp[r - (1 << k) + 1][k]);
}
bool check(int L1, int R1, int L2, int R2) {
return (L1 <= L2 && R1 >= L2) || (L1 <= R2 && R1 >= R2) || (L2 <= L1 && R2 >= L1) || (L2 <= R1 && R2 >= R1);
}
int vis[MX];
int main() {
#ifdef local
freopen("in.txt", "r", stdin);
#endif // local
char op[2];
int T, m; cin >> T;
while(T--) {
scanf("%d", &m);
int ans = 1, x; n = 0;
memset(vis, 0, sizeof(vis));
memset(ch, 0, sizeof(ch));
rep(i, 0, m) {
scanf("%d %s", &x, op);
assert(x > 0 && x <= 10000);
ch[--x] = op[0]; n = max(n, x + 1);
if(vis[x] && vis[x] != op[0]) ans = 0;
vis[x] = op[0];
}
ST(n);
int a = n + 1, b = n + 1, c = n + 1, mark = 0;
for(int N = 1; N <= n + 1; N++) {
int LA = 0, RA = 0, LB = n, RB = 0, LC = n, RC = N - 1;
for(int i = 0; i < n; i += N) {
int l = i, r = min(i + N - 1, n - 1);
RA = max(RA, RMQ_max(A, l, r) - l);
LC = min(LC, RMQ_min(C, l, r) - l);
LB = min(LB, RMQ_min(Bl, l, r) - l);
RB = max(RB, RMQ_max(Br, l, r) - l);
}
int flag = 1, cnt1 = 0, cnt2 = 0, cnt3 = 0;
if(check(LA, RA, LC, RC)) flag = 0;
if(LB <= RB && check(LA, RA, LB, RB)) flag = 0;
if(LB <= RB && check(LB, RB, LC, RC)) flag = 0;
cnt1 = max(cnt1, RA - LA + 1);
if(LB <= RB) {
cnt2 = max(cnt2, RB - RA);
cnt3 = max(cnt3, RC - RB);
} else {
cnt3 = max(cnt3, RC - RA);
}
if(flag) {
mark = 1;
if(a > cnt1) a = cnt1, b = cnt2, c = cnt3;
else if(a == cnt1 && b > cnt2) b = cnt2, c = cnt3;
else if(a == cnt1 && b == cnt2 && c > cnt3) c = cnt3;
}
}
if(!mark) printf("NO\n");
else printf("%d %d %d\n", a, b, c);
}
#ifdef local
cout << "time cost:" << clock() << "ms" << endl;
#endif // local
return 0;
}