题目描述
Byteasar runs a confectionery in Byteburg.
Strawberry-vanilla flavoured lollipops are the favourite of local children.
These lollipops are composed of multiple segments of the same length, each segment of either strawberry or vanilla flavour.
The price of the lollipop is the sum of the values of its segments, where a vanilla segment costs one bythaler, while a strawberry segments costs two.
Fig. 1: An exemplary lollipop of five segments, three strawberry flavoured and two vanilla, alternately.
The price of this lollipop is 88 bythalers.
Currently Byteasar is left with only one lollipop, though possibly very long.
As a salesman, he knows only too well that probably no one will want to buy the whole lollipop. For this reason he thinks of breaking the lollipop at the joints of the segments in order to get a shorter lollipop. Each fragment for sale, of course, must stay in one piece.
Byteasar vast experience of a salesman, as well as his understanding of children psychology, tell him that his young customers will most likely want to spend all their money on a single lollipop. With this in mind, he wonders for which values of kk the lollipop he has can be broken down in such a way that as a result one would get, among other pieces, a lollipop worth exactly kk bythalers.
Naturally, he is interested in the way of breaking the lollipop as well.
As this task overwhelms him, he asks you for help.
给一个只有1和2的序列,每次询问有没有一个子串的和为x
输入输出格式
输入格式:
In the first line of the standard input there are two integers nn and mm ( 1≤n,m≤1 000 000 ), separated by a single space.
These denote, respectively, the number of segments of the last lollipop left in store, and the number of values of kk to consider.
The lollipop's segments are numbered from 1 to nn .
The second line gives an nn -letter description of the lollipop, consisting of letters T and W, where T denotes a strawberry flavoured segment, while W - vanilla flavoured;the ii -th of these letters specifies the flavour of the ii -th segment.
In the following mm lines successive values of kk ( 1≤k≤2 000 000 ) to consider are given, one per line.
输出格式:
Your program should print out exactly mm lines, giving, one per line, the results for successive values of kk , to the standard output.
If for a given value of kk it is impossible to break the lollipop in such a way that there is a contiguous fragment worth exactly kk bythalers, then the word NIE (no in Polish) should be printed. Otherwise, two integers ll and rr ( n1≤l≤r≤n ), separated by single spaces, should be printed, such that the fragment of the lollipop composed of the segments numbered from ll to rr inclusively is worth exactly kk bythalers. If there are multiple such pairs, your program is free to choose one arbitrarily.
输入输出样例
说明
给一个只有1和2的序列,每次询问有没有一个子串的和为x
SPJ对于格式的要求较为严格。对于每个询问后,应紧跟一个换行符。在最后一次输出你的答案以及一个换行符后不应有任何输出。
由zhouyonglong提供SPJ
一个小性质:对于奇数x来说,如果能被凑出来,那么比x小的都能被凑出来。偶数同理,证明很简单:
考虑让一个数减少2 。如果当前区间左边或右边有一个2,我们移动不选这个2就可以了 。那么如果没有2呢?那么左右两边一定是两个1,同时向中间移动即可。
那么我们只要找出最大的奇数和偶数即可。首先把数组的总和算出来,就可以确定奇数或偶数的最大。剩下的一个呢?易证凑出这个数的区间一定有一个端点在1或N。只要再分别找出离两边最远的1在哪里就好了。这样我们把区间按照刚刚所说的方法操作一定可以移动出所有数的答案。
总复杂度O(N)
#include<cstdio> #include<algorithm> using namespace std; const int maxn = 1e6 + 5; char s[maxn]; int n, m, u, iodd, sum, cnt1, cnt2, l[2], r[2], evod[2]; int pre[maxn], Al[maxn], Ar[maxn]; void Shrink(int x, int l, int r) { while(1) { Al[x] = l, Ar[x] = r; if(s[l] == 2) ++l; else if(s[r] == 2) --r; else if(l < r - 1) ++l, --r; else return x -= 2, Al[x] = l, Ar[x] = r, void(); x -= 2; } } int main() { scanf("%d%d", &n, &m); scanf("%s", s + 1); for(register int i = 1; i <= n; ++i) { if(s[i] == 'T') s[i] = 2, ++cnt2; else s[i] = 1, ++cnt1; sum += s[i]; } iodd = bool(sum & 1); evod[iodd] = sum, l[iodd] = 1, r[iodd] = n; for(register int i = 1; i <= n; ++i) pre[i] = pre[i - 1] + s[i]; for(register int i = n; i >= 1; --i) if((pre[i] & 1) == !iodd) {evod[iodd ^ 1] = pre[i], l[iodd ^ 1] = 1, r[iodd ^ 1] = i; break ;} for(register int i = 1; i <= n; ++i) if(((pre[n] - pre[i - 1]) & 1) == !iodd) if(evod[iodd ^ 1] < pre[n] - pre[i - 1]) { evod[iodd ^ 1] = pre[n] - pre[i - 1]; l[iodd ^ 1] = i, r[iodd ^ 1] = n; break ; } Shrink(evod[0], l[0], r[0]); Shrink(evod[1], l[1], r[1]); Al[0] = Ar[0] = 0; for(register int i = 1; i <= m; ++i) { scanf("%d", &u); if(Al[u]) printf("%d %d\n", Al[u], Ar[u]); else printf("NIE\n"); } return 0; }
没有帐号? 立即注册