UVaLive LA 4726 UVa 1451 - Average (子序列最大平均数 数形结合 斜率优化 单调队列)

来源:互联网 发布:perl python 哪个好 编辑:程序博客网 时间:2024/05/16 19:56

Average

Time Limit:3000MS Memory Limit:Unknown 64bit IO Format:%lld & %llu

[Submit]  [Go Back]  [Status]  

Description

Download as PDF

A DNA sequence consists of four letters, A, C, G, and T. The GC-ratio of a DNA sequence is the number of Cs and Gs of the sequence divided by the length of the sequence. GC-ratio is important in gene finding because DNA sequences with relatively high GC-ratios might be good candidates for the starting parts of genes. Given a very long DNA sequence, researchers are usually interested in locating a subsequence whose GC-ratio is maximum over all subsequences of the sequence. Since short subsequences with high GC-ratios are sometimes meaningless in gene finding, a length lower bound is given to ensure that a long subsequence with high GC-ratio could be found. If, in a DNA sequence, a 0 is assigned to every A and T and a 1 to every C and G, the DNA sequence is transformed into a binary sequence of the same length. GC-ratios in the DNA sequence are now equivalent to averages in the binary sequence.


Position         11111111Index12345678901234567Sequence00101011011011010


For the binary sequence above, if the length lower bound is 7, the maximum average is 6/8 which happens in the subsequence [7,14]. Its length is 8, which is greater than the length lower bound 7. If the length lower bound is 5, then the subsequence [7,11] gives the maximum average 4/5. The length is 5 which is equal to the length lower bound. For the subsequence [7,11], 7 is its starting index and 11 is its ending index.

Given a binary sequence and a length lower bound L, write a program to find a subsequence of the binary sequence whose length is at leastL and whose average is maximum over all subsequences of the binary sequence. If two or more subsequences have the maximum average, then find the shortest one; and if two or more shortest subsequences with the maximum average exist, then find the one with the smallest starting index.

Input

Your program is to read from standard input. The input consists of T test cases. The number of test cases T is given in the first line of the input. Each test case starts with a line containing two integersn(1$ \le$n$ \le$100, 000) and L(1$ \le$L$ \le$1, 000) which are the length of a binary sequence and a length lower bound, respectively. In the next line, a string, binary sequence, of lengthn is given.

Output

Your program is to write to standard output. Print the starting and ending index of the subsequence.

The following shows sample input and output for two test cases.

Sample Input

2 17 5 00101011011011010 20 4 11100111100111110000

Sample Output

7 11 6 9

Source

Seoul 2009-2010


题意:求平均数最大的子序列

参考 周源论文 《浅谈数形结合思想在信息学竞赛中的应用》



样例一组

1
47 17
11001001010010011011010000001001101001010100001


ans:
5 22


#include <cstdio>#include <iostream>#include <vector>#include <algorithm>#include <cstring>#include <string>#include <map>#include <cmath>#include <queue>#include <set>using namespace std;//#define WIN#ifdef WINtypedef __int64 LL;#define iform "%I64d"#define oform "%I64d\n"#define oform1 "%I64d"#elsetypedef long long LL;#define iform "%lld"#define oform "%lld\n"#define oform1 "%lld"#endif#define S64I(a) scanf(iform, &(a))#define P64I(a) printf(oform, (a))#define P64I1(a) printf(oform1, (a))#define REP(i, n) for(int (i)=0; (i)<n; (i)++)#define REP1(i, n) for(int (i)=1; (i)<=(n); (i)++)#define FOR(i, s, t) for(int (i)=(s); (i)<=(t); (i)++)const int INF = 0x3f3f3f3f;const double eps = 1e-10;const double PI = (4.0*atan(1.0));const int maxn = 100000 + 20;char s[maxn];int sum[maxn];int Q[maxn];double ratio(int st, int ed) {    return (sum[ed] - sum[st]) * 1.0 / (ed - st);}int main() {    int T;    //freopen("data.in", "r", stdin);    //freopen("data1.out", "w", stdin);    scanf("%d", &T);    while(T--) {        int n, L;        scanf("%d%d", &n, &L);        scanf("%s", s+1);        sum[0] = 0;        for(int i=1; i<=n; i++) {            sum[i] = sum[i-1] + s[i] - '0';        }        double maxavg = -1;        int ansl = 0;        int ansr = 0;        int front = 0, rear = -1;        for(int i=L; i<=n; i++) {            while(front < rear && ratio(Q[rear-1], Q[rear])+eps > ratio(Q[rear], i-L))                rear--;            Q[++rear] = i - L;            while(front < rear && ratio(Q[front], i) < ratio(Q[front+1], i)+eps)                front++;            double t = ratio(Q[front], i);            if(t > maxavg + eps || (fabs(t-maxavg) < eps && i-Q[front] < ansr-ansl)) {                maxavg = t;                ansl = Q[front];                ansr = i;            }        }        printf("%d %d\n", ansl+1, ansr);    }    return 0;}




0 0
原创粉丝点击