hdu4339 Query(multiset 或 线段树)
Query
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 998 Accepted Submission(s): 300
Problem Description
You are given two strings s1[0..l1], s2[0..l2] and Q - number of queries.
Your task is to answer next queries:
1) 1 a i c - you should set i-th character in a-th string to c;
2) 2 i - you should output the greatest j such that for all k (i<=k and k<i+j) s1[k] equals s2[k].
Your task is to answer next queries:
1) 1 a i c - you should set i-th character in a-th string to c;
2) 2 i - you should output the greatest j such that for all k (i<=k and k<i+j) s1[k] equals s2[k].
Input
The first line contains T - number of test cases (T<=25).
Next T blocks contain each test.
The first line of test contains s1.
The second line of test contains s2.
The third line of test contains Q.
Next Q lines of test contain each query:
1) 1 a i c (a is 1 or 2, 0<=i, i<length of a-th string, 'a'<=c, c<='z')
2) 2 i (0<=i, i<l1, i<l2)
All characters in strings are from 'a'..'z' (lowercase latin letters).
Q <= 100000.
l1, l2 <= 1000000.
Next T blocks contain each test.
The first line of test contains s1.
The second line of test contains s2.
The third line of test contains Q.
Next Q lines of test contain each query:
1) 1 a i c (a is 1 or 2, 0<=i, i<length of a-th string, 'a'<=c, c<='z')
2) 2 i (0<=i, i<l1, i<l2)
All characters in strings are from 'a'..'z' (lowercase latin letters).
Q <= 100000.
l1, l2 <= 1000000.
Output
For each test output "Case t:" in a single line, where t is number of test (numbered from 1 to T).
Then for each query "2 i" output in single line one integer j.
Then for each query "2 i" output in single line one integer j.
Sample Input
1
aaabba
aabbaa
7
2 0
2 1
2 2
2 3
1 1 2 b
2 0
2 3
aaabba
aabbaa
7
2 0
2 1
2 2
2 3
1 1 2 b
2 0
2 3
Sample Output
Case 1:
2
1
0
1
4
1
Source
题意:第一行输入一个整数,表示案例数;然后输入两个字符串;再然后输入一个数,表示操作的次数;
两个操作:
1 a i c 更新:表示第 a(a=1或a=2)个字符串中下标为 i 的字符用 c 替换;
2 i 访问:表示两个字符串从下标为 i 开始有多个字符是一样的。
法一:把所以不能匹配的下标存储在 multiset

1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<set> 5 #define MAXN 1000010 6 7 using namespace std; 8 9 char s[2][MAXN]; 10 11 int main() 12 { 13 int test,n,i,j,len1,len2,p,q,k=1; 14 char c[2]; 15 multiset<int>ms; 16 multiset<int>::iterator it; 17 scanf("%d",&test); 18 while(test--) 19 { 20 ms.clear(); 21 scanf("%s",s[0]); 22 scanf("%s",s[1]); 23 len1=strlen(s[0]); 24 len2=strlen(s[1]); 25 i=0; 26 while(i<len1&&i<len2) 27 { 28 if(s[0][i]!=s[1][i]) ms.insert(i); 29 i++; 30 } 31 ms.insert(i); 32 printf("Case %d:\n",k++); 33 scanf("%d",&n); 34 for(i=0;i<n;i++) 35 { 36 scanf("%d",&p); 37 if(p==2) 38 { 39 scanf("%d",&j); 40 it=ms.lower_bound(j); 41 printf("%d\n",*it-j); 42 } 43 else 44 { 45 scanf("%d %d %s",&q,&j,c); 46 q--; 47 if(s[0][j]!=s[1][j]) ms.erase(j); 48 s[q][j]=*c; 49 if(s[q^1][j]!=s[q][j]) ms.insert(j); 50 } 51 } 52 } 53 return 0; 54 }
法二:线段树中存储这区间第一个不能匹配的下标,转换成单点更新,区间最值

1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define MAXN 1000000 5 6 struct segtree 7 { 8 int left,right,acount; 9 }tree[MAXN<<2]; 10 char s[2][MAXN]; 11 int INF; 12 13 int min(int A,int B){return A<B?A:B;} 14 15 int max(int A,int B){return A>B?A:B;} 16 17 void build(int r,int a,int b) 18 { 19 tree[r].left=a;tree[r].right=b; 20 tree[r].acount=INF; 21 if(a<b) 22 { 23 int m=(a+b)>>1; 24 build(r<<1,a,m); 25 build(r<<1|1,m+1,b); 26 } 27 } 28 29 void update(int r,int i,int key) 30 { 31 if(tree[r].left==tree[r].right) 32 { 33 tree[r].acount=key; 34 return ; 35 } 36 int m=(tree[r].left+tree[r].right)>>1; 37 if(i<=m) 38 update(r<<1,i,key); 39 else 40 update(r<<1|1,i,key); 41 tree[r].acount=min(tree[r<<1].acount,tree[r<<1|1].acount); 42 } 43 44 int find_min(int r,int a,int b) 45 { 46 if(a<=tree[r].left&&tree[r].right<=b) 47 return tree[r].acount; 48 int m=(tree[r].left+tree[r].right)>>1; 49 if(b<=m) 50 return find_min(r<<1,a,b);//对自己很无语了居然写成find_min(r<<1,a,m); 51 else if(a>m) 52 return find_min(r<<1|1,a,b);//这里也是 53 else 54 return min(find_min(r<<1,a,m),find_min(r<<1|1,m+1,b)); 55 } 56 57 int main() 58 { 59 60 #ifndef ONLINE_JUDGE 61 freopen("in.txt","r",stdin); 62 freopen("out.txt","w",stdout); 63 #endif 64 65 int test,i,j,k=1,n,p,q,len; 66 char c[2]; 67 scanf("%d",&test); 68 while(test--) 69 { 70 scanf("%s",s[0]); 71 scanf("%s",s[1]); 72 len=min(strlen(s[0]),strlen(s[1])); 73 INF=len+1; 74 build(1,1,len); 75 for(i=0;i<len;i++) 76 { 77 if(s[0][i]!=s[1][i]) update(1,i+1,i+1); 78 else update(1,i+1,INF); 79 } 80 printf("Case %d:\n",k++); 81 scanf("%d",&n); 82 for(i=0;i<n;i++) 83 { 84 scanf("%d",&p); 85 if(p==2) 86 { 87 scanf("%d",&j); 88 if(j>=len) 89 printf("0\n"); 90 else 91 printf("%d\n",find_min(1,j+1,len)-j-1); 92 } 93 else if(p==1) 94 { 95 scanf("%d %d %s",&q,&j,c); 96 if(j>=len) continue; 97 q--; 98 if(s[q][j]==s[q^1][j]&&s[q^1][j]!=*c) update(1,j+1,j+1); 99 if(s[q][j]!=s[q^1][j]&&s[q^1][j]==*c) update(1,j+1,INF); 100 s[q][j]=*c; 101 } 102 } 103 } 104 return 0; 105 }