zoukankan      html  css  js  c++  java
  • HDU 4339 Query (线段树)

    Query

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


    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
     
    Source
     
    Recommend
    zhoujiaqi2010

    题意: 有两个字符串,给出 Q 个询问,每个询问有两种体式格式:

    1 p i c 把第 p 个字符串的第i 个字符换成 字符 c,

    2 i     从第位i 开始,两个字符串连续相同的子串的最大长度为多少。

    思路:普通的查找肯定超时,所以用线段树 复杂度大概为O(n + Qlog(n)) 每个结点保存该区间内第一个不匹配的下标,query时,只需找到与key(要查找的点) 最近的一个下标 相减就得

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    #define L(rt) (rt<<1)
    #define R(rt) (rt<<1|1)
    
    const int maxn=1000010;
    
    struct node{
        int l,r;
        int lab;    //lab表示在当前区间内第一个不匹配的下标
    }tree[maxn*3];
    
    char str[2][maxn];
    int tmp,a,b;
    
    void build(int l,int r,int rt){
        tree[rt].l=l;
        tree[rt].r=r;
        tree[rt].lab=tmp;
        if(l==r)
            return;
        int mid=(l+r)>>1;
        build(l,mid,L(rt));
        build(mid+1,r,R(rt));
    }
    
    void update(int key,int lab,int rt){
        if(tree[rt].l==tree[rt].r){
            tree[rt].lab=lab;
            return ;
        }
        int mid=(tree[rt].l+tree[rt].r)>>1;
        if(key<=mid)    
            update(key,lab,L(rt));
        else
            update(key,lab,R(rt));
        tree[rt].lab=min(tree[L(rt)].lab,tree[R(rt)].lab);
    }
    
    int query(int key,int rt){
        if(key<=tree[rt].l) //只需要找>= key 的范围
            return tree[rt].lab;
        if(key<=tree[L(rt)].r)
            a=query(key,L(rt)); //a 原初始化为tmp
        b=query(key,R(rt)); //右边的肯定满足
        return min(a,b);    
    }
    
    int main(){
    
        //freopen("input.txt","r",stdin);
    
        int T,Q;
        char c;
        scanf("%d",&T);
        int cases=0;
        while(T--){
            scanf("%s%s",str[0],str[1]);
            int len=min(strlen(str[0]),strlen(str[1]));
            tmp=len+1;
            build(1,len,1);
            for(int i=0;i<len;i++)
                if(str[0][i]!=str[1][i])
                    update(i+1,i+1,1);
                else
                    update(i+1,tmp,1);
            scanf("%d",&Q);
            printf ("Case %d:\n",++cases);
            int op,s,k;
            while(Q--){
                scanf("%d",&op);
                if(op==2){
                    scanf("%d",&k);
                    a=tmp;
                    int ans=query(k+1,1)-(k+1);
                    printf("%d\n",ans);
                }else{
                    scanf("%d %d %c",&s,&k,&c);
                    s--;    //只有两种情况需要更新
                    if(str[s][k]==str[s^1][k] && str[s^1][k]!=c)    //原来两字符相等 改后不等了
                        update(k+1,k+1,1);
                    if(str[s][k]!=str[s^1][k] && str[s^1][k]==c)    //原两字符不等 改后相等了
                        update(k+1,tmp,1);
                    str[s][k]=c;
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    使用jxl.jar操作Excel
    ThreadLocal学习
    ArrayList与Vector、HashMap与HashTable
    String, StringBuffer, StringBuilder比较
    ArrayList与LinkedList实现比较
    Java文件备份类
    Maven安装与更新
    Eclipse安装反编译工具JadClipse
    Linux关闭防火墙
    Hadoop简介
  • 原文地址:https://www.cnblogs.com/jackge/p/3038637.html
Copyright © 2011-2022 走看看