http://acm.hdu.edu.cn/showproblem.php?pid=3474

单调队列,又是第一次使用,本人蒟蒻无比啊。。。

hdu 3474
 1#include <cstdio>
 2#include <iostream>
 3#include <cmath>
 4#include <complex>
 5#include <algorithm>
 6#include <cstring>
 7#include <queue>
 8using namespace std;
 9
10const int maxn = 1000000 + 10;
11int Q[maxn<<1], sum[maxn<<1];
12char neck[maxn<<1];
13int vis[2][maxn];
14
15void solve( int n, int m, int v )
16{
17    sum[0= 0;
18    forint i = 1; i < m; i++ )
19        sum[i] = sum[i-1+ ( neck[i] == 'C' ? 1 : -1 );
20    int head = 0, tail = 0;
21    forint i = 0; i < m; i++ )
22    {
23        while( head < tail && sum[Q[tail-1]] >= sum[i] ) tail--;
24        Q[tail++= i;
25        if( i >= n )
26        {
27            while( i - Q[head] >= n ) head++;
28            vis[v][i-n] = ( sum[i-n] <= sum[Q[head]] );
29        }

30    }

31}

32
33int main(int argc, char *argv[])
34{
35    int t;
36    scanf("%d",&t);
37    forint p = 1; p <= t; p++ )
38    {
39        scanf("%s",neck+1);
40        int n = strlen( neck + 1 );
41        int m = n * 2 + 1;
42        forint i = 1; i <= n; i++ )
43            neck[i+n] = neck[i];
44        neck[m] = 0;
45        memset( vis, 0sizeof( vis ) );
46        solve( n, m, 0 );
47        reverse( neck + 1, neck + m );
48        solve( n, m, 1 );
49        int ans = 0;
50        forint i = 1; i <= n; i++ )
51            if( vis[0][i] || vis[1][n-i] ) ans ++;
52        printf("Case %d: %d\n",p,ans);
53    }

54    return 0;
55}

56