您的位置:首页 > 其它

HDU P4339(树状数组+二分查询)

2012-08-02 21:33 330 查看



Query

[b]Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 198 Accepted Submission(s): 79



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.

[/b]
这是今天多校的全场题。。。我用的线段树。。。。TLE到死。。。结束后写了个树状数组的。。。靠

/*
* =====================================================================================
*
*       Filename:  P1009.cpp
*
*    Description:
*
*        Version:  1.0
*        Created:  2012年08月02日 20时00分56秒
*       Revision:  none
*       Compiler:  gcc
*
*         Author:  Mad13 (),
*   Organization:
*
* =====================================================================================
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <algorithm>

#define Mid(a) ((a)>>1)
#define R(a) (((a)<<1)+1)
#define L(a) ((a)<<1)
#define maxn 1010000
#define Clear(a,b) memset(a,b,sizeof(a))

int Max(int a,int b)
{
if (a > b) return a;
return b;
}

int Min(int a,int b)
{
if (a > b) return b;
return a;
}

char s[2][maxn];
int in[maxn],ar[maxn],n;

int lowbit(int t)
{
return t&(t^(t-1));
}

int sum(int end)
{
int sum = 0;
while(end > 0)
{
sum += in[end];
end -= lowbit(end);
}
return sum;
}

int sum2(int a,int b)
{
return sum(b) - sum(a-1);
}

void plus(int pos,int num)
{
while(pos <= n)
{
in[pos] += num;
pos += lowbit(pos);
}
}

int p = 0;

int work()
{
scanf("%s%s",s[0],s[1]);
printf("Case %d:\n",++p);
n = Min(strlen(s[0]),strlen(s[1]))+1;
//printf("xx%d\n",n);
int a,i,b,l,r,m,t,k;
char c;
Clear(in,0);
Clear(ar,0);
for(i = 0;i < n;i++) plus(i+1,s[0][i] == s[1][i]);
//for(i = 0;i < n;i++) printf("%d\n",sum(i+1));
scanf("%d",&k);
for(i = 1;i <= k;i++) {
scanf("%d",&t);
if (t == 1) {
scanf("%d%d %c",&a,&b,&c);
a--;
//printf("%s\n%s\n",s[0],s[1]);
if (s[a][b] != c && s[1-a][b] == c) plus(b+1,1);
if (s[a][b] == s[1-a][b] && s[1-a][b] != c) plus(b+1,-1);
//for(i = 1;i <= n;i++) printf("%d ",sum(i));
//printf("\n");
s[a][b] = c;
}
else {
scanf("%d",&a);
a++;
l = a;r = n;
while(l < r) {
//printf("%d %d\n",l,r);
m = Mid(l + r);
//printf("%d  %d %d\n",a,m,sum2(a,m));
if ((m - a + 1) > sum2(a,m)) r = m;
else l = m + 1;
//printf("___%d %d\n",l,r);
}
printf("%d\n",l - a);
}
}
return 0;
}

int main()
{
int t;
scanf("%d",&t);
while(t--) work();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: