題目意思:
給兩個字符串,有兩種操作。
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; }