【树状数组】The 36th ACM/ICPC Asia Regional Beijing Site Online Contest - G Panda

来源:互联网 发布:手机正规淘宝刷単软件 编辑:程序博客网 时间:2024/04/29 16:49

 http://cnc.boj.me/onlinejudge/newoj/showProblem/show_problem.php?problem_id=217

其他人都说用线段树,可是自己敲着敲着就没想法,只好转向树状数组,发现可以实现,貌似比别人的线段树快。

 

方法:一直维护wbw中第一个w,把它记为1,然后整个数组更新。求和比较头疼,第一是下标要加1,第二是很容易求错。

后来想了想,发现只要sum(r-2)-sum(l-1),其中l和r都转化为以1为开始下标。

#include <map>#include <set>#include <list>#include <queue>#include <deque>#include <stack>#include <string>#include <time.h>#include <cstdio>#include <math.h>#include <iomanip>#include <cstdlib>#include <limits.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;#define LL long long#define PI acos(-1.0)#define MAX INT_MAX#define MIN INT_MIN#define FRE freopen("a.txt","r",stdin)#define N 50005#define MOD 10007int c[N];char str[N];int lowbit(int t){    return t&(-t);}void update(int pos,int v){    while(pos<N){        c[pos]+=v;        pos+=lowbit(pos);    }}int sum(int pos){    int tot=0;    while(pos){        tot+=c[pos];        pos-=lowbit(pos);    }    return tot;}int main(){    int tt;    scanf("%d",&tt);    int ca=1;    while(tt--){        int n,m;        scanf("%d%d",&n,&m);        int i,j;        scanf("%s",str);        memset(c,0,sizeof(c));        for(i=0;i+2<n;i++){            if(str[i]=='w' && str[i+1]=='b' && str[i+2]=='w'){                    update(i+1,1);                }        }        printf("Case %d:\n",ca++);        while(m--){            int a;            scanf("%d",&a);            if(!a){                int s,t;                scanf("%d%d",&s,&t);                if(t-s+1<=2)printf("%d\n",0);                else{                    int l=s+1;                    int r=t+1;                    printf("%d\n",sum(r-2)-sum(l-1));                }            }            else{                int pos;                char cc;                scanf("%d %c",&pos,&cc);                int s;                int t;                s=(pos-2>=0) ? pos-2 : 0 ;                t=(pos+2<n) ? pos+2 : n-1 ;                for(i=s;i+2<=t;i++)                if(str[i]=='w' && str[i+1]=='b' && str[i+2]=='w'){                    update(i+1,-1);                }                str[pos]=cc;                for(i=s;i+2<=t;i++)                    if(str[i]=='w' && str[i+1]=='b' && str[i+2]=='w'){                        update(i+1,1);                    }                }            }        }    return 0;}
原创粉丝点击