首页 > 代码库 > HDU 4339 (线段树字符标记)
HDU 4339 (线段树字符标记)
题意:两字符串s1,s2,给定若干查询。
查询操作:
1 a b c 把第a个字符串的第b个字符换成字符c
2 a 查询从第a个字符开始s1[k]==s2[k],的个数。例如 aaa aab 查询 2 0 结果是2
思路:线段树的叶子值设为出现不同的位置i+1,初始为len+1;没次查询区间最小值,即最先不同的位置;
#include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<algorithm> #define N 1000010 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; char s[2][N]; int val[N<<2]; int INF; void pushup(int rt) { val[rt]=min(val[rt<<1],val[rt<<1|1]); } void build(int l,int r,int rt) { val[rt]=INF; if(l==r) return; int m=(l+r)>>1; build(lson); build(rson); } void update(int p,int v,int l,int r,int rt) { if(l==r) { val[rt]=v; return; } int m=(l+r)>>1; if(p<=m) update(p,v,lson); else update(p,v,rson); pushup(rt); } int query(int L,int R,int l,int r,int rt) { //cout<<"---"<<endl; int ans=INF; if(L<=l&&r<=R) { return val[rt]; } int m=(l+r)>>1; if(L<=m) ans=min(ans,query(L,R,lson)); if(R>m) ans=min(ans,query(L,R,rson)); return ans; } int main() { int T; scanf("%d",&T); for(int cas=1;cas<=T;cas++) { scanf("%s%s",s[0],s[1]); int len=min(strlen(s[0]),strlen(s[1])); INF=len+1; build(1,len,1); for(int i=0;i<len;i++) { if(s[0][i]==s[1][i]) update(i+1,INF,1,len,1); else update(i+1,i+1,1,len,1); } int n,op; int a,b; char c[2]; scanf("%d",&n); printf("Case %d:\n",cas); for(int i=0;i<n;i++) { scanf("%d",&op); if(op==2) { scanf("%d",&a); if(a>=len) printf("0\n"); else printf("%d\n",query(a+1,len,1,len,1)-a-1); } else { scanf("%d%d%s",&b,&a,c); if(a>=len) continue; b--; if(s[b][a]==s[b^1][a]&&s[b^1][a]!=c[0]) update(a+1,a+1,1,len,1); if(s[b][a]!=s[b^1][a]&&s[b^1][a]==c[0]) update(a+1,INF,1,len,1); s[b][a]=c[0]; } } } return 0; }
HDU 4339 (线段树字符标记)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。