首页 > 代码库 > HDU 4339 (线段树字符标记)

HDU 4339 (线段树字符标记)

题意:两字符串s1,s2,给定若干查询。

         查询操作:

                  1 a b c 把第a个字符串的第b个字符换成字符c

                  2 a   查询从第a个字符开始s1[k]==s2[k],的个数。例如 aaa aab 查询 2 0 结果是2


思路:线段树的叶子值设为出现不同的位置i+1,初始为len+1;没次查询区间最小值,即最先不同的位置;


#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#define N 1000010
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;

char s[2][N];
int val[N<<2];
int INF;

void pushup(int rt)
{
    val[rt]=min(val[rt<<1],val[rt<<1|1]);
}

void build(int l,int r,int rt)
{
    val[rt]=INF;
    if(l==r)
        return;
    int m=(l+r)>>1;
    build(lson);
    build(rson);
}

void update(int p,int v,int l,int r,int rt)
{
    if(l==r)
    {
        val[rt]=v;
        return;
    }
    int m=(l+r)>>1;
    if(p<=m) update(p,v,lson);
    else update(p,v,rson);
    pushup(rt);
}

int query(int L,int R,int l,int r,int rt)
{
    //cout<<"---"<<endl;
    int ans=INF;
    if(L<=l&&r<=R)
    {
        return val[rt];
    }
    int m=(l+r)>>1;
    if(L<=m) ans=min(ans,query(L,R,lson));
    if(R>m) ans=min(ans,query(L,R,rson));
    return ans;
}


int main()
{
    int T;
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++)
    {
        scanf("%s%s",s[0],s[1]);
        int len=min(strlen(s[0]),strlen(s[1]));
        INF=len+1;
        build(1,len,1);
        for(int i=0;i<len;i++)
        {
            if(s[0][i]==s[1][i]) update(i+1,INF,1,len,1);
            else update(i+1,i+1,1,len,1);
        }
        int n,op;
        int a,b;
        char c[2];
        scanf("%d",&n);
        printf("Case %d:\n",cas);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&op);
            if(op==2)
            {
                scanf("%d",&a);
                if(a>=len)
                    printf("0\n");
                else
                    printf("%d\n",query(a+1,len,1,len,1)-a-1);
            }
            else
            {
                scanf("%d%d%s",&b,&a,c);

                if(a>=len)
                    continue;
                b--;
                if(s[b][a]==s[b^1][a]&&s[b^1][a]!=c[0]) update(a+1,a+1,1,len,1);
                if(s[b][a]!=s[b^1][a]&&s[b^1][a]==c[0]) update(a+1,INF,1,len,1);
                s[b][a]=c[0];
            }
        }
    }
    return 0;
}


HDU 4339 (线段树字符标记)