HDU 4339 Query
生活随笔
收集整理的這篇文章主要介紹了
HDU 4339 Query
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意: 有兩個字符串,給出 Q 個詢問,每個詢問有兩種方式:
???????? 1 p i c 把第 p 個字符串的第i 個字符換成 字符 c,
???????? 2 i????? 從位置i 開始,兩個字符串連續相同的子串的最大長度為多少。
分析: 線段樹。
????????? 數組len[rt] 保存rt 區間從最左端開始的最長子串,
???????? 合并時,如果len[rt<<1]==mid-l+1? 則 len[rt]=len[rt<<1]+len[rt<<1|1]? ,說明可以把右兒子區間直接接到左兒子區間上,否則由于左兒子區間與右兒子區間斷開,
???????? len[rt]=len[rt<<1].
#include<stdio.h> #include<string.h> #include<stdlib.h> const int maxn=1000005; char s1[maxn]; char s2[maxn]; int len[maxn<<3]; void creat(int l,int r,int rt) {if(l==r){len[rt]=(s1[l]==s2[l]);return;}int m=(l+r)>>1;creat(l,m,rt<<1);creat(m+1,r,rt<<1|1);len[rt]=len[rt<<1];if(len[rt<<1]==m-l+1)len[rt]+=len[rt<<1|1]; } void update(int l,int r,int rt,int i,int x) {if(l==r){len[rt]=x;return;}int m=(l+r)>>1;if(i<=m)update(l,m,rt<<1,i,x);else update(m+1,r,rt<<1|1,i,x);len[rt]=len[rt<<1];if(len[rt<<1]==m-l+1)len[rt]+=len[rt<<1|1]; } int query(int l,int r,int rt,int i) {int res=0;if(l==i)return len[rt];int m=(l+r)>>1;if(i<=m){res+=query(l,m,rt<<1,i);if(res==m-i+1)res+=len[rt<<1|1];}else res+=query(m+1,r,rt<<1|1,i);return res; } int main() {int l1,l2,p,l,t,n,ca=1,k,c,flag;char s[2];scanf("%d",&t);while(t--){scanf("%s%s",s1+1,s2+1);l1=strlen(s1+1);l2=strlen(s2+1);l=l1<l2?l1:l2;creat(1,l,1);printf("Case %d:\n",ca++);scanf("%d",&n);while(n--){scanf("%d",&p);if(p==1){scanf("%d%d%s",&c,&k,s);if(k>=l)continue;flag=0;if(s1[k+1]==s2[k+1])flag=1;if(c==1)s1[k+1]=s[0];else s2[k+1]=s[0];if(s1[k+1]==s2[k+1]&&flag==0)update(1,l,1,k+1,1);else if(s1[k+1]!=s2[k+1]&&flag==1)update(1,l,1,k+1,0);}else {scanf("%d",&k);if(k>=l)printf("0\n");elseprintf("%d\n",query(1,l,1,k+1));}}}return 0; }?
轉載于:https://www.cnblogs.com/dream-wind/archive/2012/08/03/2622306.html
總結
以上是生活随笔為你收集整理的HDU 4339 Query的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Oracle LogMiner分析a
- 下一篇: 数据库修复Part1:创建自己的测试co