hdu 4339 Query

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4339

线段树或者 树状数组+二分

记录两个字符串在该区间内有多少个字符相匹配。

线段树:

View Code
  1 # include<stdio.h>

  2 # include<string.h>

  3 # include<stdlib.h>

  4 # define N 1000005

  5 char s1[N],s2[N];

  6 struct node{

  7     int l,r;

  8     int num;

  9 }tree[4*N];

 10 void bulid(int l,int r,int t)

 11 {

 12     int mid;

 13     tree[t].l=l;

 14     tree[t].r=r;

 15     tree[t].num=0;

 16     if(l==r) 

 17     {

 18         if(s1[l]==s2[l]) tree[t].num=1;

 19         return;

 20     }

 21     mid=(l+r)/2;

 22     bulid(l,mid,2*t);

 23     bulid(mid+1,r,2*t+1);

 24     tree[t].num=tree[2*t].num+tree[2*t+1].num;

 25 }

 26 void updata1(int l,int t)

 27 {

 28     tree[t].num--;

 29     if(tree[t].l==tree[t].r) return;

 30     if(l<=tree[2*t].r) updata1(l,2*t);

 31     else updata1(l,2*t+1);

 32 }

 33 void updata2(int l,int t)

 34 {

 35     tree[t].num++;

 36     if(tree[t].l==tree[t].r) return;

 37     if(l<=tree[2*t].r) updata2(l,2*t);

 38     else updata2(l,2*t+1);

 39 }

 40 int query(int l,int r,int t)

 41 {

 42     int ans1;

 43     if(tree[t].r - tree[t].l + 1 == tree[t].num) return r-l+1;

 44     if(tree[t].l==tree[t].r) return tree[t].num;

 45     if(r<=tree[2*t].r) return query(l,r,2*t);

 46     else if(l>=tree[2*t+1].l) return query(l,r,2*t+1);

 47     else

 48     {

 49         ans1=query(l,tree[2*t].r,2*t);

 50         if(ans1==tree[2*t].r-l+1)

 51         {

 52             return ans1+query(tree[2*t+1].l,r,2*t+1);

 53         }

 54         else return ans1;

 55     }

 56 }

 57 int main()

 58 {

 59     int ncase,t;

 60     int l1,l2;

 61     int count,ans,ss,h,Q,flag;

 62     char ch;

 63     scanf("%d",&ncase);

 64     for(t=1;t<=ncase;t++)

 65     {

 66         scanf("%s",s1);

 67         scanf("%s",s2);

 68         l1=strlen(s1);

 69         l2=strlen(s2);

 70         ans=l1;

 71         if(l2<ans) ans=l2;

 72         bulid(0,ans-1,1);

 73         scanf("%d",&Q);

 74         printf("Case %d:\n",t);

 75         while(Q--)

 76         {

 77             scanf("%d",&ss);

 78             if(ss==1)

 79             {

 80                 scanf("%d%d %c",&flag,&h,&ch);

 81                 if(flag==1)

 82                 {

 83                     //s1[h]=ch;

 84                     if(h<l2 && s1[h]==s2[h] && s1[h]!=ch) updata1(h,1);

 85                     else if(h<l2 && s1[h]!=s2[h] && ch==s2[h]) updata2(h,1);

 86                     s1[h]=ch;

 87                 }

 88                 else

 89                 {

 90                     if(h<l1 && s1[h]==s2[h] && ch!=s1[h]) updata1(h,1);

 91                     else if(h<l1 && s1[h]!=s2[h] && ch==s1[h]) updata2(h,1);

 92                     s2[h]=ch;

 93                 }

 94             }

 95             else

 96             {

 97                 scanf("%d",&h);

 98                 count=query(h,ans-1,1);

 99                 printf("%d\n",count);

100             }

101         }

102     }

103     return 0;

104 }

树状数组+二分

View Code
  1 # include<stdio.h>

  2 # include<string.h>

  3 # include<stdlib.h>

  4 # define N 1000005

  5 char s1[N],s2[N];

  6 int sum[N];

  7 void updata1(int x,int n)

  8 {

  9     while(x<=n)

 10     {

 11         sum[x]++;

 12         x += (x&(-x));

 13     }

 14 }

 15 void updata2(int x,int n)

 16 {

 17     while(x<=n)

 18     {

 19         sum[x]--;

 20         x+=(x&(-x));

 21     }

 22 }

 23 int query(int x)

 24 {

 25     int num=0;

 26     while(x>=1)

 27     {

 28         num+=sum[x];

 29         x-=(x&(-x));

 30     }

 31     return num;

 32 }

 33 int main()

 34 {

 35     int ncase,t,i;

 36     int l1,l2,ans,ans1,ans2;

 37     int l,r,mid;

 38     int flag,num,h,Q;

 39     char ch;

 40     scanf("%d",&ncase);

 41     for(t=1;t<=ncase;t++)

 42     {

 43         scanf("%s",s1+1);

 44         scanf("%s",s2+1);

 45         l1=strlen(s1+1);

 46         l2=strlen(s2+1);

 47         ans=l1;

 48         if(l2<ans) ans=l2;

 49         memset(sum,0,sizeof(sum));

 50         for(i=1;i<=ans;i++)

 51         {

 52             if(s1[i]==s2[i]) updata1(i,ans);

 53         }

 54         printf("Case %d:\n",t);

 55         scanf("%d",&Q);

 56         while(Q--)

 57         {

 58             scanf("%d",&flag);

 59             if(flag==1)

 60             {

 61                 scanf("%d%d %c",&num,&h,&ch);

 62                 h++;

 63                 if(num==1)

 64                 {

 65                     if(h<l2 && s1[h]!=s2[h] && ch==s2[h]) updata1(h,ans);

 66                     else if(h<l2 && s1[h]==s2[h] && ch!=s1[h]) updata2(h,ans);

 67                     s1[h]=ch;

 68                 }

 69                 else

 70                 {

 71                     if(h<l1 && s1[h]!=s2[h] && ch==s1[h]) updata1(h,ans);

 72                     else if(h<l1 && s1[h]==s2[h] && ch!=s2[h]) updata2(h,ans);

 73                     s2[h]=ch;

 74                 }

 75             }

 76             else

 77             {

 78                 scanf("%d",&h);

 79                 h++;

 80                 l=h;

 81                 r=ans;

 82                 num=0;

 83                 ans1=query(h-1);

 84                 while(l<=r)

 85                 {

 86                     mid=(l+r)/2;

 87                     ans2=query(mid);

 88                     if(ans2-ans1==mid-h+1)

 89                     {

 90                         num=mid-h+1;

 91                         l=mid+1;

 92                     }

 93                     else r=mid-1;

 94                 }

 95                 printf("%d\n",num);

 96             }

 97         }

 98     }

 99     return 0;

100 }

 

 

你可能感兴趣的:(query)