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 }

posted on 2012-08-08 16:15  矮人狙击手!  阅读(385)  评论(0)    收藏  举报

导航