hdu4339(线段树)
线段树啊,有是线段树,有点东西老是搞不懂,build,update ,query,这三个函数到底怎么写,还是不太懂啊
有时候看代码真的很抽象,画个图或许可以帮助理解
1 #include <iostream> 2 #include <string.h> 3 #include <cstring> 4 #include <stdio.h> 5 using namespace std; 6 char b[1000005],f[1000005]; 7 int first,a,d; 8 int min(int a ,int b) 9 { 10 return a>b?b:a; 11 } 12 struct tree 13 { 14 int left; 15 int right; 16 int index;//第一个不匹配的下标 17 }; 18 tree node[1000005*4]; 19 void build(int left,int right,int root)//初始化每个节点中的index,值为一个不合乎规范的数,min(strlen(b),strlen(f))+1 20 { 21 node[root].left=left; 22 node[root].right=right; 23 node[root].index=first; 24 if(node[root].left==node[root].right) 25 { 26 return ;//已经没有子节点了,所以结束,返回上一父节点,不可和前面三句话换顺序,否则叶节点未初始化 27 } 28 int mid=(left+right)/2; 29 build(left,mid,root*2); 30 build(mid+1,right,root*2+1); 31 } 32 33 void update(int index,int first,int root)//node[]的下标无法计算,只能从根结点一步一步推,更新从每一个叶节点开始 34 { 35 if(node[root].left==node[root].right) 36 { 37 node[root].index=first; 38 return ;//注意return的使用,如果不写无法返回到上一级,递归无法实现 39 } 40 int mid=(node[root].left+node[root].right)/2; 41 if(index<=mid) 42 { 43 update(index,first,root*2); 44 } 45 else 46 { 47 update(index,first,root*2+1); 48 } 49 node[root].index=min(node[root*2].index,node[root*2+1].index); 50 51 } 52 53 int query(int index,int root) 54 { 55 if(index<=node[root].left) 56 { 57 return node[root].index; 58 } 59 int mid=(node[root].left+node[root].right)/2; 60 if(index<=mid) 61 { 62 a=query(index,root*2);//查询左子树,因为每次都要对d进行赋值,多以没有必要为d赋初值,不过a就不一样了,a为全局变量初始值为0,所以要为a赋一个稍大点的值 63 } 64 d=query(index,root*2+1);//注意每次都要对左右两边进行query(),所以这里没有else 65 return min(a,d); 66 67 } 68 int main() 69 { 70 int count=1; 71 int Case,i,num; 72 //cin>>Case; 73 scanf("%d",&Case); 74 int q; 75 while(Case--) 76 { 77 //cin>>b>>f; 78 scanf("%s%s",b,f); 79 int n=min(strlen(b),strlen(f)); 80 first=n+1; 81 build(1,n,1); 82 for(i=0;i<n;i++) 83 { 84 if(b[i]!=f[i]) update(i+1,i+1,1);//第一个i+1为在node[]中的序号 85 else update(i+1,first,1); 86 } 87 //cin>>q; 88 scanf("%d",&q); 89 //cout<<"Case "<<count++<<":"<<endl; 90 printf("Case %d:\n",count++); 91 int flag; 92 int x,y; 93 char c; 94 for(i=0;i<q;i++) 95 { 96 //cin>>flag; 97 scanf("%d",&flag); 98 if(flag==2) 99 { 100 //cin>>num; 101 scanf("%d",&num); 102 //这里是否应该实现给a赋一个值? 103 a=first; 104 int ans=query(num+1,1)-(num+1); 105 //cout<<ans<<endl; 106 printf("%d\n",ans); 107 } 108 else 109 { 110 //cin>>x>>y>>c; 111 scanf("%d %d %c",&x,&y,&c);//注意c语言单个字符的输入 112 if(x==1) 113 { 114 if(b[y]==f[y] && f[y]!=c) update(y+1,y+1,1); 115 if(b[y]!=f[y] && f[y]==c) update(y+1,first,1); 116 b[y]=c; 117 } 118 else 119 { 120 if(f[y]==b[y] && b[y]!=c) update(y+1,y+1,1); 121 if(f[y]!=b[y] && b[y]==c) update(y+1,first,1); 122 f[y]=c; 123 } 124 125 } 126 } 127 } 128 return 0; 129 }
浙公网安备 33010602011771号