hdu 4339 Query 一道挺好的树状数组题(树状数组+二分思想)
题意:首先给了两个字符串,然后有两种类型的操作,第一种:1 a i c 你应该把第i个字符串的第a个字符变成c;第二种:2 i 就是问你从第i个字符开始两个字符串连续的最长的相等长度。
思路:利用树状数组更新和求和,对于第二种操作就是利用二分求得的连续最长的长度。
代码实现:
#include<iostream> #include<cstring> using namespace std; char str1[1000001],str2[1000001]; int a[1000001],len1,len2; int lowbit(int x) { return x&(-x); } void build(int x,int num)//构造树状数组 { while(x<=len1) { a[x]=a[x]+num; x=x+lowbit(x); } } int sum(int x)//求和 { int s=0; while(x>=1) { s=s+a[x]; x=x-lowbit(x); } return s; } int main() { int T,nima,i,Q,x1,x2,x3,nima1,nima2; char temp; while(scanf("%d",&T)!=EOF) { getchar(); nima=0; while(T--) { nima++; scanf("%s%s",str1+1,str2+1);//数组下标从1开始 printf("Case %d:\n",nima); len1=strlen(str1+1); len2=strlen(str2+1); len1=len1>len2?len2:len1;//去两者中短的 for(i=0;i<=len1;i++) a[i]=0;//树状数组的初始化 for(i=1;i<=len1;i++) if(str1[i]==str2[i]) build(i,1); scanf("%d",&Q); while(Q--) { scanf("%d",&x1); if(x1==1) { scanf("%d%d %c",&x2,&x3,&temp); getchar(); if(x3+1<=len1) { if(x2==1)//对第一个字符串进行操作 { if(str1[x3+1]==str2[x3+1]&&str2[x3+1]!=temp) build(x3+1,-1); else if(str1[x3+1]!=str2[x3+1]&&str2[x3+1]==temp) build(x3+1,1); str1[x3+1]=temp; } else { if(str1[x3+1]==str2[x3+1]&&str1[x3+1]!=temp) build(x3+1,-1); else if(str1[x3+1]!=str2[x3+1]&&str1[x3+1]==temp) build(x3+1,1); str2[x3+1]=temp; } } } else { scanf("%d",&x2); if(x2>len1) printf("%d\n",0); else { nima1=x2+1;nima2=len1; while(nima1<=nima2)//二分思想 { int mid=(nima1+nima2)/2; if((sum(mid)-sum(nima1-1))==(mid-nima1+1))//左边连续 nima1=mid+1; else//左边不连续 nima2=mid-1; } printf("%d\n",nima2-x2); } } } } } return 0; }
posted on 2013-01-19 22:29 后端bug开发工程师 阅读(358) 评论(0) 编辑 收藏 举报