hdu3474單調隊列

來源:互聯網
上載者:User

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

 

題意:給你一個只包含C和J的項鏈(10^6),問從哪些位置切了之後從改位置往後到每個位置C的個數都不小於J的個數。。。兩個方向均可。。。求有多少個位置滿足。。

 

 

分析:記得這是去年多校的題。。那時候還不會。。先加倍,從前往後求和sum[i],其實就是要保證對i元素後面的n個元素滿足:min(sum[i+1...i+n])-sum[i]>=0

所以轉化一下就是維護一個n的區間內的最小值而已。。。很水的單調隊列了。。注意向兩端求的時候結果對應的位置一定要正確。。。

 

做起來都是浮雲。。。迅速從題意分析出模型才是王道。。。

 

 

代碼:

#include<iostream>#include<stdio.h>using namespace std;const int N=4000100;char s[N];int sum[N], ans[N], q[N];int n, head, tail;int main(){    int i, j, tmp, cnt, cas1=1, T;    scanf("%d", &T);    while(T--)    {        scanf("%s", s);        n = strlen(s);        for(i=0; i<n; i++)            s[i+n] = s[i];        s[2*n] = 0;                for(i=0; i<2*n; i++)            ans[i] = 0;        tmp = 0;        for(i=0; i<2*n; i++)        {            if(s[i]=='C')    tmp++;            else    tmp--;            sum[i] = tmp;        }        head = tail = 0;        for(i=0; i<n; i++)        {            while(head<tail && sum[q[tail-1]]>sum[i])                tail--;            q[tail++] = i;        }        if(sum[q[head]]>=0)            ans[0] = 1;        for(; i<2*n; i++)        {            while(head<tail && sum[q[tail-1]]>sum[i])                tail--;            q[tail++] = i;            while(i-q[head]>=n)                head++;            if(sum[q[head]]-sum[i-n]>=0)                ans[i-n+1] = 1;        }        tmp = 0;        for(i=2*n-1; i>=0; i--)        {            if(s[i]=='C')    tmp++;            else    tmp--;            sum[i] = tmp;        }        head = tail = 0;        for(i=2*n-1; i>=n; i--)        {            while(head<tail && sum[q[tail-1]]>sum[i])                tail--;            q[tail++] = i;        }        if(sum[q[head]]>=0)            ans[n] = 1;        for(; i>0; i--)        {            while(head<tail && sum[q[tail-1]]>sum[i])                tail--;            q[tail++] = i;            while(q[head]-i>=n)                head++;            if(sum[q[head]]-sum[i+n]>=0)                ans[i] = 1;        }        cnt = 0;        for(i=1; i<n; i++)            cnt += ans[i];        if(ans[0]==1 || ans[n]==1)            cnt++;        printf("Case %d: %d\n", cas1++, cnt);    }    return 0;}

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.