hdoj 4339 线段树 单点更新,区间查询
2013-03-10 22:36
387 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4339
题意: 给两个字符串,Q组操作,更新操作时更改某个字符串的某个字符,查询操作是询问从某个点i开始两个字符串最长的公共子串。
解题思路: 线段树,Tree[rt] 存放的是l-r这个区间从最左边开始的公共子串的长度。 分两种情况,case1,左子区间的串完全匹配,那么Tree[rt]=Tree[rt<<1]+Tree[rt<<1|1],case2,Tree[rt]=Tree[rt<<1]。单点更新也就不需要lazy标记了。区间查询怎么查呢?Query(L,R,l,r,rt)代表查询l-r区间与L-R区间重合的部分的以左端点起始的最长公共子串长度...这样就好理解了...
题意: 给两个字符串,Q组操作,更新操作时更改某个字符串的某个字符,查询操作是询问从某个点i开始两个字符串最长的公共子串。
解题思路: 线段树,Tree[rt] 存放的是l-r这个区间从最左边开始的公共子串的长度。 分两种情况,case1,左子区间的串完全匹配,那么Tree[rt]=Tree[rt<<1]+Tree[rt<<1|1],case2,Tree[rt]=Tree[rt<<1]。单点更新也就不需要lazy标记了。区间查询怎么查呢?Query(L,R,l,r,rt)代表查询l-r区间与L-R区间重合的部分的以左端点起始的最长公共子串长度...这样就好理解了...
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<vector> #include<stack> #include<queue> using namespace std; #define NIL NULL #define INF 0x7fffffff #define DINF 1e9 #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define maxn 1000005 int Tree[maxn<<2]; char S1[maxn],S2[maxn]; void Build(int l,int r,int rt) { if(l==r) { if(S1[l-1]==S2[l-1]) Tree[rt]=1; else Tree[rt]=0; return ; } int mid=(l+r)>>1; Build(lson); Build(rson); if(Tree[rt<<1]==(mid-l+1)) Tree[rt]=Tree[rt<<1]+Tree[rt<<1|1]; else Tree[rt]=Tree[rt<<1]; } void Show(int l,int r,int rt) { cout<<l<<" "<<r<<" "<<Tree[rt]<<endl; if(l==r) return ; int mid=(l+r)>>1; Show(lson); Show(rson); } int Query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) return Tree[rt]; if(L>r||R<l) return 0; int mid=(l+r)>>1,tmp,tl; if(L<=mid) { tl=max(L,l); tmp=Query(L,R,lson); if(tmp==(mid-tl+1)) tmp+=Query(L,R,rson); return tmp; } else { tmp=Query(L,R,rson); return tmp; } } void Update(int i,int l,int r,int rt) { if(l==r) { if(S1[l-1]==S2[l-1]) Tree[rt]=1; else Tree[rt]=0; return ; } int mid=(l+r)>>1; if(i<=mid) Update(i,lson); else Update(i,rson); Tree[rt]=Tree[rt<<1]; if(Tree[rt<<1]==mid-l+1) Tree[rt]+=Tree[rt<<1|1]; return ; } int main() { int T,Q,o,a,i,j,c,len,tmp,cnt=0; char ch; scanf("%d",&T); while(T--) { cnt++; scanf("%s",S1); scanf("%s",S2); scanf("%d",&Q); len=min(strlen(S1),strlen(S2)); Build(1,len,1); // Show(1,len,1); printf("Case %d:\n",cnt); while(Q--) { scanf("%d",&o); if(o==1) { scanf("%d %d",&a,&i); getchar(); scanf("%c",&ch); if(a==1) S1[i]=ch; else S2[i]=ch; Update(i+1,1,len,1); } else { scanf("%d",&i); i++; tmp=Query(i,len,1,len,1); j=tmp; printf("%d\n",j); } } } return 0; }
相关文章推荐
- hdoj 5493 Queue 【线段树 单点更新 + 区间查询】
- hdoj 4819 Mosaic 【二维线段树 单点更新 区间查询】
- HDOJ 4325 Flowers 【线段树 离散化 区间更新 单点查询】
- HDOJ-2795 Billboard [线段树][单点更新+单点查询+维护区间最值]
- HDOJ-2795 Billboard [线段树][单点更新+单点查询+维护区间最值]
- HDOJ 5316 Magician【线段树 单点更新 区间查询】
- hdoj 4325 Flowers 【线段树 + 离散化】【区间更新 单点查询】
- FZU Problem 2240 Daxia & Suneast's problem(博弈+[单点更新,区间查询]线段树)
- POJ 3264 Balanced Lineup (线段树单点更新 区间查询)
- HDOJ 1754 I Hate It (线段树单点更新求区间最大值)
- HDU.1166 敌兵布阵 (线段树 单点更新 区间查询)
- 线段树入门 单点更新区间查询 南阳oj 116
- NYOJ-568/1012//UVA-12299RMQ with Shifts,线段树单点更新+区间查询
- NBOJv2 1050 Just Go(线段树/树状数组区间更新单点查询)
- 线段树 HDU 4217 Data Structure? 单点更新 区间查询
- HDOJ-1166(线段树点更新 + 区间查询)
- HDU.1556 Color the ball (线段树 区间更新 单点查询)
- hdu 1556 Color the ball(线段树区间更新单点查询+懒惰标记)
- SPOJ 375 QTREE - Query on a tree 树链剖分+线段树(单点更新 区间查询最值)
- !POJ 2352 左下角星星-线段树-(单点更新,区间查询)