Query

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


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
 
AC代码:

#include<stdio.h>
#include<string.h>
#define lowbit(a) (a&(-a))
#define N 1000005
#define MIN(a,b) (a>b?a:b)
int num[N];
char s[2][N];
int n;

void update(int a,int b)
{
  while(a<=n)
  {
     num[a]+=b;
  a+=lowbit(a);    
  }  
}

int sum1(int x)
{
   int sum=0;
   while(x)
   {
      sum+=num[x];
      x-=lowbit(x);    
   }  
   return sum;
}

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

int main()
{
   int t=0;
   int cnt=1;
   scanf("%d",&t);
   while(t--)
   {
     printf("Case %d:\n",cnt++);
      memset(num,0,sizeof(num));
   scanf("%s%s",s[0],s[1]);
   n=MIN(strlen(s[0]),strlen(s[1]));
   for(int i=0;i<n;i++)
   update(i+1,s[0][i]==s[1][i] ); 
   int k;
   int p,a,b,x;
   char c;
   scanf("%d",&k);
   while(k--)
   {
      scanf("%d",&p);
   if(p==1)
   {
      scanf("%d%d %c",&a,&b,&c);
   a--;
   if(s[a][b]!=c&&s[1-a][b]==c)
   update(b+1,1);
   if(s[a][b]==s[1-a][b]&&s[a][b]!=c)
   update(b+1,-1);
   s[a][b]=c;   
         }  
   if(p==2)
   {
      scanf("%d",&x);
   x++;
   int l=x;
   int r=n;
   while(l<=r)//二分查询;
   {
     int m=(l+r)/2;
     if(sum2(x,m)<(m-x+1))
     r=m-1;
     else
     l=m+1;     
   }   
   printf("%d\n",l-x);
         }  
      }  
   }
   return 0;  
}

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