线段树-hdu-4339-Query

2014-11-23 20:16:27 · 作者: · 浏览: 7

题目意思:

给两个字符串,有两种操作。

1、改变一字符串的某个位置的一个字符。

2、查找某一位置开始的最大的连续的两串相同的字符的个数。

解题思路:

线段树维护两个值:该区间最左边连续的最大值,最右边连续的最大值。

每做一道题,停下思考,抽象出一点体会。

代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define eps 1e-6
#define INF 0x1f1f1f1f
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define Maxn 1100000
/*
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
*/
struct Node
{
   int ls,rs;
}node[Maxn*4]; //线段树维护区间两个值,1、包括左端点位置的最大连续相等的个数,
//2、包括右端点位置的最大连续相等的个数
char sa1[Maxn],sa2[Maxn];
int nm,n;

void pushup(int rt,int num) //向上更新
{
   node[rt].ls=node[rt<<1].ls;
   node[rt].rs=node[rt<<1|1].rs;

   if(node[rt].ls>=num-(num>>1)) //左孩子区间个数为num-(num>>1)
      node[rt].ls+=node[rt<<1|1].ls;
   if(node[rt].rs>=(num>>1)) //右孩子区间个数为num>>1
      node[rt].rs+=node[rt<<1].rs;

}

void build(int l,int r,int rt)
{
   if(l==r)
   {
      if(l>1;
   build(lson);
   build(rson);
   pushup(rt,r-l+1);
}

void update(int k,int l,int r,int rt)
{
   if(l==r)
   {
      if(l>1;
   if(k<=m)
      update(k,lson);
   else
      update(k,rson);
   pushup(rt,r-l+1);
}

int query(int k,int l,int r,int rt)
{
   if(l==r)
      return 1; //该位置一定是相同的
   int m=(l+r)>>1;
   if(k<=m)
   {
      if(node[rt<<1].rs>m-k) //只用从该位置向右考虑就行了
         return m-k+1+node[rt<<1|1].ls;
      else
         return query(k,lson);
   }
   else
      return query(k,rson);


}


int main()
{
//   scanf("%s",sa1);
//   scanf("%s",sa1);
//   printf("%c\n",sa1[5]);
   int t;
   int ab,po,m,ki;
   char s[5];

   scanf("%d",&t);
   for(int ca=1;ca<=t;ca++)
   {
      scanf("%s",sa1);
      scanf("%s",sa2);
      int len1=strlen(sa1),len2=strlen(sa2);
      n=max(len1,len2);
      nm=min(len1,len2);
      build(0,n-1,1);
      printf("Case %d:\n",ca);
      scanf("%d",&m);
      while(m--)
      {
         scanf("%d",&ki);
         if(ki==1)
         {
            scanf("%d%d%s",&ab,&po,s);
            if(ab==1)
               sa1[po]=*s;
            else
               sa2[po]=*s;
            update(po,0,n-1,1);
         }
         else
         {
            scanf("%d",&po);
            if(po>=nm||sa1[po]!=sa2[po])
            {
               printf("0\n");
               continue;
            }
            printf("%d\n",query(po,0,n-1,1));

         }
      }
   }
   return 0;
}