【线段树】【HUD1698】Just a Hook (回头补坑)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698

刚开始看到这个题的时候还自作聪明,这次不是区间集体增加一个值了,而是更改为某个值 ,想到我不用线段树了不就好了,反正只是最后只查询一次

我每次都给它修改好了,也不建树了,最后输出之前来遍历一遍······然后就TLE了,看来还是处理不来数据量比较大的情况的,复杂度O(N)但是常数太大

 1 #include <string>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 using namespace std;
 6 
 7 const int N = 100010;
 8 int num[N];
 9 
10 int main()
11 {
12     int t,n,q,x,y,b,i,j;
13     int ca = 1;
14     cin >> t;
15     while(t--)
16     {
17                 memset(num,0,sizeof num);
18         scanf("%d",&n);
19         for(i = 1;i <= n;i++)
20             num[i] = 1;
21         scanf("%d",&q);
22         for(i = 1;i <= q;i++)
23         {
24             scanf("%d %d %d",&x,&y,&b);
25             for(j = x;j <= y;j++)
26                 num[j] = b;
27         }
28         int p = 0;
29         for(i = 1;i <= n;i++)
30             p += num[i];
31         printf("Case %d: The total value of the hook is %d.
",ca++,p);
32     }
33     
34     return 0;
35 }
36 
37 // 一不小心删代码删多了 又补了几行 反正不是AC代码  问题不大 2333
View Code

 这下就不得不用线段树了,但是这次单点更新不是加一个值了,所以需要改一改之前的代码  

原本是+t或者-t  现在修改为+(t-num[i])   这样就巧妙的避开了问题   但是提交后仍然TLE   还需要进行优化

 1 #include <string>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 
 6 using namespace std;
 7 
 8 #define N 100001
 9 
10 int num[N];
11 struct node 
12 {
13     int l,r;
14     int sum;
15     int mid()
16     {
17         return (l+r)/2;
18     }
19 }tree[N*4];
20 
21 void BuildTree(int root,int l,int r)
22 {
23     tree[root].l = l;
24     tree[root].r = r;
25     if(l == r)
26     {
27         tree[root].sum = num[l];
28         return ;
29     }
30     BuildTree(root*2,l,(l+r)/2);
31     BuildTree(root*2+1,(l+r)/2+1,r);
32     tree[root].sum = tree[root*2].sum+tree[root*2+1].sum;
33 }
34 
35 void add(int root,int i,int t)
36 {
37     tree[root].sum += (t-num[i]);
38     if(tree[root].l == i && tree[root].r == i)
39     {
40         num[i] = t;
41         return ;
42     }
43     if(i <= tree[root].mid())
44         add(root*2,i,t);
45     else
46         add(root*2+1,i,t);
47 }
48 
49 int query(int root,int s,int e)
50 {
51     if(tree[root].l == s && tree[root].r == e)
52         return tree[root].sum;
53     if(e <= tree[root].mid())
54         return query(root*2,s,e);
55     else
56         if(s > tree[root].mid())
57             return query(root*2+1,s,e);
58         else
59             return query(root*2,s,tree[root].mid())+query(root*2+1,tree[root].mid()+1,e);
60 }
61 
62 int main()
63 {
64     int t,n,q,x,y,b,i,j;
65     int ca = 1;
66     cin >> t;
67     while(t--)
68     {
69         scanf("%d",&n);
70         for(i = 1;i <= n;i++)
71             num[i] = 1;
72         BuildTree(1,1,n);
73         scanf("%d",&q);
74         for(i = 1;i <= q;i++)
75         {
76             scanf("%d %d %d",&x,&y,&b);
77             for(j = x;j <= y;j++)
78             {
79                 add(1,j,b);
80             }
81         }
82         
83         printf("Case %d: The total value of the hook is %d.
",ca++,query(1,1,n));
84     }
85     
86     return 0;
87 }
View Code

终于在看过别人的写法以后AC了  但是现在还是对线段树不是很理解

稍后会打上详细注释

 1 #include <string>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 
 6 using namespace std;
 7 
 8 #define N 100001
 9 
10 
11 struct node 
12 {
13     int l,r;
14     int same;
15     int sum;
16 }tree[N*4];
17 
18 void BuildTree(int root,int l,int r)
19 {
20     tree[root].l = l;
21     tree[root].r = r;
22     if(l == r)
23     {
24         tree[root].same = 1;
25         tree[root].sum = 1;
26     }
27     else
28     {
29         int mid = (l+r)/2;
30         BuildTree(root*2,l,mid);
31         BuildTree(root*2+1,mid+1,r);
32         tree[root].same = 0;
33         tree[root].sum = (tree[root*2].sum + tree[root*2+1].sum);
34     }
35 }
36 
37 void update(int root,int L,int R,int t)
38 {
39     if(tree[root].l == L && tree[root].r == R)
40     {
41         tree[root].same = t;
42         tree[root].sum = (R-L+1)*t;
43     }
44     else
45     {
46         if(tree[root].same > 0)
47         {
48             tree[root*2].same = tree[root].same;
49             tree[root*2].sum = (tree[root*2].r-tree[root*2].l+1)*tree[root*2].same;
50             tree[root*2+1].same = tree[root].same;
51             tree[root*2+1].sum = (tree[root*2+1].r-tree[root*2+1].l+1)*tree[root*2+1].same;
52         }
53         tree[root].same = 0;   // 不懂
54         int mid = (tree[root].l+tree[root].r)/2;
55         if(R <= mid)
56             update(root*2,L,R,t);
57         else
58             if(L > mid)
59                 update(root*2+1,L,R,t);
60             else
61             {
62                 update(root*2,L,mid,t);
63                 update(root*2+1,mid+1,R,t);
64             }
65         tree[root].sum = tree[root*2].sum+tree[root*2+1].sum;
66     }  
67 }
68 
69 int main()
70 {
71     int t,n,q,x,y,b,i;
72     int ca = 1;
73     cin >> t;
74     while(t--)
75     {
76         scanf("%d",&n);
77         // cout << n << endl;
78         BuildTree(1,1,n);
79         scanf("%d",&q);
80         for(i = 1;i <= q;i++)
81         {
82             scanf("%d %d %d",&x,&y,&b);
83             update(1,x,y,b);
84         }
85         printf("Case %d: The total value of the hook is %d.
",ca++,tree[1].sum);
86     }
87     
88     return 0;
89 }
View Code
文章搬运自我的个人博客http://duny31030.top 原博客为静态博客,因备份丢失无法继续更新,所以又搬运回博客园,可能部分文章阅读体验不好,可以到我的静态博客搜索相同标题查看
原文地址:https://www.cnblogs.com/duny31030/p/8879927.html