程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 線段樹-hdu-4339-Query

線段樹-hdu-4339-Query

編輯:C++入門知識

題目意思:

給兩個字符串,有兩種操作。

1、改變一字符串的某個位置的一個字符。

2、查找某一位置開始的最大的連續的兩串相同的字符的個數。

解題思路:

線段樹維護兩個值:該區間最左邊連續的最大值,最右邊連續的最大值。

每做一道題,停下思考,抽象出一點體會。

代碼:

 

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#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<nm) //兩串的最小長度
         node[rt].ls=node[rt].rs=(sa1[l]==sa2[r])?1:0;
      else
         node[rt].ls=node[rt].rs=0;
      return ;
   }
   int m=(l+r)>>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<nm)
         node[rt].ls=node[rt].rs=(sa1[l]==sa2[r])?1:0;
      else
         node[rt].ls=node[rt].rs=0;
      return ;
   }
   int m=(l+r)>>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;
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved