码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4339 线段树区间合并

时间:2014-07-26 09:51:37      阅读:272      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   java   color   os   strong   io   

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 } 

 

HDU 4339 线段树区间合并,布布扣,bubuko.com

HDU 4339 线段树区间合并

标签:des   style   blog   java   color   os   strong   io   

原文地址:http://www.cnblogs.com/qq1012662902/p/3869280.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!