hdu 4339 Query

http://acm.hdu.edu.cn/showproblem.php?pid=4339

题意:给两串字符串,有两个操作:

 1) 1 a i c - 将第a串的第i个字符修改成c;

 2) 2 i - 求两个串从第i位置开始的最长相同长度。

 思路:因为答案只和当前位置前面的有关,所以可以用树状数组。具体如下:

如果第i个位置上相同,则为0,不同则为1,这样就可以转化成求第i个位置后面一第一个1的位置。

这样用求第k大解之。(加上读入优化rank1)

View Code
#include<stdio.h>
#include<string.h>
#include<iostream>
#define lowbit(x) (x)&(-x)
using namespace std;
const int maxn = 1000005;
char as[2][maxn];
int n,sum[1<<21];
void add(int x,int v){for(;x<=n;x+=lowbit(x))sum[x]+=v;}
int getsum(int x){int v=0;for(;x;x-=lowbit(x))v+=sum[x];return v;}
int findk(int k)
{
    int pos = 0,cnt = 0;
    for(int i = 20; i >= 0; -- i){
        pos += (1<<i);
        if(pos>=n || cnt+sum[pos]>=k) pos -= (1<<i);
        else cnt += sum[pos];
    }return pos + 1;
}
int scan(){
    int res=0,ch;
    while(!((ch=getchar())>='0' && ch<='9'))
        if(ch==EOF) return 1<<30;
    res=ch-'0';
    while((ch=getchar())>='0' && ch<='9')
        res=res*10+(ch-'0');
    return res;
}
void readin()
{
    int k;
    scanf("%s%s",as[0],as[1]);
    n = strlen(as[0]);
    k = strlen(as[1]);
    if(k > n) n = k;
}
void processing()
{
    int i,j,k,t,a,b;
    char s[12];
    n++;
    for(i = 0; i < n - 1; ++ i)
    if(as[0][i]^as[1][i])
    add(i+1,1);
    sum[n] = 1;
    scanf("%d",&t);
    while(t--){
        a = scan(); b = scan();
        if(a==2){
            k = getsum(b);
            j = findk(k+1);
            printf("%d\n",j - b - 1);
        }else{
            --b;
            i = scan();
            gets(s);
            if(as[b][i]==as[b^1][i]){
                as[b][i] = s[0];
                if(s[0]^as[b^1][i])
                    add(i+1,1);
            }else{
                as[b][i] = s[0];
                if(as[b][i]==as[b^1][i])
                    add(i+1,-1);
            }
        }
    }
    for(i = 0; i <= n; ++ i){
        as[0][i] = as[1][i] = 0;
        sum[i] = 0;
    }
}
int main()
{
    int T,cas=0;
    for(scanf("%d",&T);T--;){
        readin();
        printf("Case %d:\n",++cas);
        processing();
    }
    return 0;
}

posted on 2012-08-19 10:59  aigoruan  阅读(132)  评论(0)    收藏  举报

导航