dreamxr
精诚所至,金石为开!

导航

 

【题目描述】

给定两个字符串,有两个操作

1--把其中一个串的某个位置的字符变换;

2--询问以某个位置开头的两个串完全相同的最大长度。

【分析】

可以两个字符串的相关信息转化为长为l的一个序列x(l=max(l1,l2)),若在i处两字符相同则x[i]=1否则x[i]=0,

每次更新就是线段树的单点更新,最后的询问就是从i开始的连续的最长的1的长度。

这题的更新很简单,问题是如何处理询问。

我的办法是记录区间内以左端点开始的最长的连续1的长度,询问的时候,如果点n正好被左端点开始的连续1序列覆盖,则递归结束。

否则继续递归左儿子或者右儿子。另外还要处理下横跨区间的问题(具体见代码)。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define N 1000010
 5 #define lson l,m,n<<1
 6 #define rson m+1,r,n<<1|1
 7 using namespace std;
 8 char s1[N],s2[N];
 9 int x[N];
10 int s[N<<2];
11 void PushUp(int n,int m){
12     s[n]=s[n<<1];
13     if(s[n<<1]==(m-(m>>1)))
14     s[n]+=s[n<<1|1];
15 }
16 void build(int l,int r,int n){
17     if(l==r){
18         s[n]=x[l]?1:0;
19         return;
20     }
21     int m=(l+r)>>1;
22     build(lson);
23     build(rson);
24     PushUp(n,r-l+1);
25 }
26 void update(int nn,int l,int r,int n){
27     if(l==r){
28         s[n]=x[l]?1:0;
29         return;
30     }
31     int m=(l+r)>>1;
32     if(nn<=m)
33     update(nn,lson);
34     else
35     update(nn,rson);
36     PushUp(n,r-l+1);
37 }
38 int query(int nn,int l,int r,int n){
39     if(nn-l+1<=s[n])
40     return l+s[n]-nn;
41     int m=(l+r)>>1;
42     if(nn<=m){
43         int k=query(nn,lson);
44         if(k==(m-nn+1))
45         k+=s[n<<1|1];
46         return k;
47     }
48     else
49         return query(nn,rson);
50 }
51 int main(){
52     int d=1;
53     int t;
54     scanf("%d",&t);
55     while(t--){
56         scanf("%s%s",s1,s2);
57         int l1=strlen(s1),l2=strlen(s2);
58         int l=max(l1,l2);
59         for(int i=l1;i<l;i++)
60         s1[i]='#';
61         for(int i=l2;i<l;i++)
62         s2[i]='#';
63         for(int i=1;i<=l;i++)
64             x[i]=(s1[i-1]==s2[i-1])?1:0;
65         int q,a,b,c;
66         build(1,l,1);
67         printf("Case %d:\n",d++);
68         scanf("%d",&q);
69         while(q--){
70             scanf("%d",&a);
71             if(a==2){
72                 scanf("%d",&b);
73                 if(x[b+1]==0)
74                 puts("0");
75                 else
76                 printf("%d\n",query(b+1,1,l,1));
77             }
78             else{
79                 char xx[5];
80                 scanf("%d%d%s",&b,&c,xx);
81                 if(b==1)s1[c]=xx[0];
82                 else s2[c]=xx[0];
83                 x[c+1]=(s1[c]==s2[c])?1:0;
84                 update(c+1,1,l,1);
85             }
86         }
87     }
88         return 0;
89 }
posted on 2012-08-03 21:51  dreamxr  阅读(136)  评论(0)    收藏  举报