首页 > 代码库 > HDU 4339 线段树区间合并

HDU 4339 线段树区间合并

Query

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2573    Accepted Submission(s): 851


Problem Description
You are given two strings s1[0..l1], s2[0..l2] and Q - number of queries.
Your task is to answer next queries:
  1) 1 a i c - you should set i-th character in a-th string to c;
  2) 2 i - you should output the greatest j such that for all k (i<=k and k<i+j) s1[k] equals s2[k].
 

 

Input
The first line contains T - number of test cases (T<=25).
Next T blocks contain each test.
The first line of test contains s1.
The second line of test contains s2.
The third line of test contains Q.
Next Q lines of test contain each query:
  1) 1 a i c (a is 1 or 2, 0<=i, i<length of a-th string, ‘a‘<=c, c<=‘z‘)
  2) 2 i (0<=i, i<l1, i<l2)
All characters in strings are from ‘a‘..‘z‘ (lowercase latin letters).
Q <= 100000.
l1, l2 <= 1000000.
 

 

Output
For each test output "Case t:" in a single line, where t is number of test (numbered from 1 to T).
Then for each query "2 i" output in single line one integer j.
 

 

Sample Input
1
aaabba
aabbaa
7
2 0
2 1
2 2
2 3
1 1 2 b
2 0
2 3
 

 

Sample Output
Case 1:
2
1
0
1
4
1
 
 
 
 
题目意思:
给两个字符串s1, s2, 然后m组操作,共有两种操作1和2,  若为1,输入a, i, c即把第a个字符串(a==1||a==2)的第 i 个位置处的字符用 c 替换;若为2,输入x,即s1,s2都从x开始匹配最远到第j处位置,输出j。
 
思路:
把两个字符串比较相同的元素为1否则为0放在一个数组p[]中,然后把p[]挂在线段树叶子节点处,然后往上更新。
线段树节点包含这么几个元素:l, r(左边界、右边界), lm, rm(从左边界开始1的最长连续段的长度,以右边界为止1的最长连续段的长度), mm(线段中1的最长的连续段长度)。(区间合并的老套路。。。)
其他的基本上就是老套路了,主要注意一下求和输出,还是直接看代码比较容易上手:
 
  1 #include <cstdio>  2 #include <cstring>  3 #include <algorithm>  4 #include <iostream>  5 using namespace std;  6 #define N 1000005  7 #define ll root<<1  8 #define rr root<<1|1  9 #define mid (a[root].l+a[root].r)/2 10  11 int p[1000005]; 12 char s1[1000005]; 13 char s2[1000005]; 14  15 struct node{ 16     int l, r; 17     int lm, rm, mm; 18 }a[4*N]; 19  20  21 void up(int root){                        //貌似线段树区间合并都有这个函数  22     if(a[root].l==a[root].r) return; 23     a[root].lm=a[ll].lm; 24     a[root].rm=a[rr].rm; 25     a[root].mm=max(a[ll].mm,a[rr].mm); 26     if(a[ll].lm==a[ll].r-a[ll].l+1) a[root].lm+=a[rr].lm; 27     if(a[rr].rm==a[rr].r-a[rr].l+1) a[root].rm+=a[ll].rm; 28     a[root].mm=max(max(a[root].lm,a[root].rm),max(a[root].mm,a[ll].rm+a[rr].lm)); 29 } 30  31 void build(int l,int r,int root){ 32     a[root].l=l; 33     a[root].r=r; 34     if(l==r){ 35         a[root].lm=a[root].rm=a[root].mm=p[l]; 36         return; 37     } 38     build(l,mid,ll); 39     build(mid+1,r,rr); 40     up(root); 41 } 42  43 void update(int q,int val,int root){ 44     if(a[root].l==q&&a[root].r==q){ 45         a[root].lm=a[root].mm=a[root].rm=val; 46         return; 47     } 48     if(q<=mid) update(q,val,ll); 49     else update(q,val,rr); 50     up(root); 51 } 52  53 int query(int q,int root){ 54     if(a[root].l==a[root].r){ 55         return a[root].mm; 56     } 57     if(q<=mid){ 58         if(q>=a[ll].r-a[ll].rm+1) return a[ll].r-q+1+query(mid+1,rr);        //若q在左子树且在左子树1右连续段则需要加上右子树1左连续段  59         else return query(q,ll);                          60     } 61     else{ 62         return query(q,rr); 63     } 64 } 65  66 main() 67 { 68     int t, kase=1; 69     int i, j, k, m; 70     int n1, n2; 71     int x, y, z; 72     char c[5]; 73     scanf("%d",&t); 74     while(t--){ 75         //memset(p,0,sizeof(p)); 76         printf("Case %d:\n",kase++); 77         scanf("%s%s",s1,s2); 78         n1=strlen(s1); 79         n2=strlen(s2); 80         for(i=0;i<min(n1,n2);i++){ 81             if(s1[i]==s2[i]) p[i]=1;                  //相同为1否则为0  82             else p[i]=0; 83         } 84         for(i=min(n1,n2);i<max(n1,n2);i++){ 85             p[i]=0; 86         } 87         build(0,max(n1,n2)-1,1); 88         scanf("%d",&m); 89         while(m--){ 90             scanf("%d",&z); 91             if(z==1){ 92                 scanf("%d %d %s",&x,&y,c); 93                 if(x==1){ 94                     s1[y]=c[0]; 95                 } 96                 else s2[y]=c[0]; 97                 p[y]=(s1[y]==s2[y]?1:0); 98                 update(y,p[y],1); 99             }100             else{101                 scanf("%d",&x);102                 printf("%d\n",query(x,1));103             }104         }105     }106 }