题目链接: 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 }

 

 

posted on 2012-08-14 08:25  奋斗青春  阅读(306)  评论(0编辑  收藏  举报