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 } 

HDU 4339 线段树区间合并

时间: 2024-11-05 12:36:53

HDU 4339 线段树区间合并的相关文章

hdu 3308(线段树区间合并)

LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6069    Accepted Submission(s): 2635 Problem Description Given n integers.You have two operations:U A B: replace the Ath number by B. (index

HDU 3911 线段树区间合并

北京赛区快了,准备袭击数据结构和图论.倒计时 18天,线段树区间合并.维护一个最长连续.. 题意:给一个01串,以下有一些操作,问区间最长的连续的1的个数 思路:非常裸的线段树区间合并 #include<iostream> #include<cstdio> #include<map> #include<set> #include<cmath> #define lson id << 1 #define rson id <<

hdu 3308 线段树 区间合并+单点更新+区间查询

LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6592    Accepted Submission(s): 2866 Problem Description Given n integers.You have two operations:U A B: replace the Ath number by B. (index

hdu 1806(线段树区间合并)

Frequent values Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1476    Accepted Submission(s): 541 Problem Description You are given a sequence of n integers a1 , a2 , ... , an in non-decreasin

HDU 3308 LCIS (线段树区间合并)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[mid + 1] > a[mid],写的细心点就好了. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int MAXN = 1

HDU 5316 Magician(线段树区间合并入门)

本文纯属原创,转载请注明出处谢谢.http://blog.csdn.net/zip_fan. 题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5316 Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description Fantasy magicians usually gain their ability

HDU 3911 Black And White(线段树区间合并)

Problem Description There are a bunch of stones on the beach; Stone color is white or black. Little Sheep has a magic brush, she can change the color of a continuous stone, black to white, white to black. Little Sheep like black very much, so she wan

HDU 3308 LCIS(最长连续上升子序列)(线段树区间合并)

题意:给你n个整数,有两种操作,U A B把第A个数变成B,Q A B查询区间[A,B]的最长连续上升序列. 思路:还是查询和更新操作,而且也是询问区间中满足条件的连续最长区间 ,所以是线段树区间合并类型的题,通法是开三棵线段树,一个记录此区间内的LCIS的最长长度,一个记录从左边第一个数开始的LCIS长度,另一个记录从右边最后一个数结尾的LCIS长度.然后试图找到父亲与儿子关系维护的递推关系式就好 本题中的递推关系是: 1. 左儿子最右边的值 < 右儿子最左边的值 lmx = (左儿子的lmx

hdu5316 Magician(线段树区间合并)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5316 题意:有n个精灵,每个精灵有一个能力值,有两种操作①改变某一个精灵的能力值②查询区间[L,R]里面位置奇偶相间的能力值的最大和. 分析:这题线段树区间合并可以做.每个节点保存4个信息:①以奇位置开始偶位置结束的奇偶序列最大和②以奇位置开始奇位置结束的奇偶序列最大和③以偶位置开始偶位置结束的奇偶序列最大和④以偶位置开始奇位置结束的奇偶序列最大和 合并的时候,以奇位置开始偶位置结束的奇偶序列最大和=m