首页 > 其他 > 详细

wenbao与线段树

时间:2018-04-14 14:42:40      阅读:189      评论:0      收藏:0      [点我收藏+]

敌兵布阵

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e5;
 4 struct Node{
 5     int left;
 6     int right;
 7     int sum;
 8 } N[maxn*4];
 9 
10 void init(int l,int r,int num){
11     N[num].left = l;
12     N[num].right = r;
13     N[num].sum = 0;
14     if(N[num].left == N[num].right)  return ;
15     int mid = (N[num].left + N[num].right) >> 1;
16     init(l, mid, num<<1);
17     init(mid+1, r, num<<1|1);
18 }
19 
20 void add(int x,int y,int num){
21     if(N[num].left == N[num].right){
22         N[num].sum += y;
23         return ;
24     }
25     int mid = (N[num].left + N[num].right) >> 1;
26     if(x <= mid)
27         add(x, y, num<<1);
28     else
29         add(x, y, num<<1|1);
30     N[num].sum = N[num<<1].sum + N[num<<1|1].sum;
31 }
32 
33 int findn(int ll,int rr,int num){
34     if(N[num].left == ll && N[num].right == rr){
35         return N[num].sum;
36     }
37     int mid = N[num].left + N[num].right>>1;
38     if(ll > mid){
39         return findn(ll, rr, num<<1|1);
40     }
41     else if(rr <= mid){
42         return findn(ll, rr, num<<1);
43     }
44     else
45     return findn(ll, mid, num<<1) + findn(mid+1, rr, num<<1|1);
46 }
47 
48 int main(){
49     int t, n, m, countn = 1;
50     char str[20];
51     scanf("%d", &t);
52     while(t--){
53         scanf("%d", &n);
54         init(1,n,1);
55         for(int i = 1; i <= n; i++){
56             scanf("%d", &m);
57             add(i, m, 1);
58         }
59         printf("Case %d:\n", countn++);
60         while(~scanf("%s", str)){
61             if(str[0] == E)
62             break;
63             if(str[0] == A){
64                 int a, b;
65                 scanf("%d%d", &a, &b);
66                 add(a, b, 1);
67             }
68             if(str[0] == S){
69                 int a, b;
70                 scanf("%d%d", &a, &b);
71                 add(a, -b, 1);
72             }
73             if(str[0] == Q){
74                 int a, b;
75                 scanf("%d%d", &a, &b);
76                 printf("%d\n", findn(a,b,1));
77             }
78         }
79     }
80     return 0;
81 }

 

-------------------------------------------------------------------

 http://poj.org/problem?id=2828

排队。。此题妙哉

 目的是求第k大数,线段树和都可以树状数组

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <cmath>
 4 using namespace std;
 5 #define ls node<<1
 6 #define rs node<<1|1
 7 const int maxn = 200009;
 8 int n, a[maxn], b[maxn], c[maxn];
 9 struct Node{
10     int l, r, num;
11 }sum[maxn*4];
12 void build(int l, int r, int node){
13     sum[node].l = l, sum[node].r = r, sum[node].num = r-l+1;
14     if(l == r) return;
15     int mid = (l+r)>>1;
16     build(l, mid, ls);
17     build(mid+1, r, rs);
18 }
19 int add(int id, int node){
20     sum[node].num --;
21     if(sum[node].l == sum[node].r){
22         return sum[node].l;
23     }
24     if(sum[ls].num >= id) add(id, ls);
25     else id -= sum[ls].num, add(id, rs);
26 }
27 int main(){
28     while(~scanf("%d", &n)){
29         build(1, n, 1);
30         for(int i = 0; i < n; ++i){
31             scanf("%d%d", &a[i], &b[i]);
32         }
33         for(int i = n-1; i >= 0; --i){
34             c[add(a[i]+1, 1)] = b[i];
35         }
36         for(int i = 1; i <= n; ++i){
37             printf("%d%c", c[i], i == n ? \n :  );
38         }
39     }
40     return 0;
41 }

 

-------------------------------------------------------------------

http://poj.org/problem?id=3277

 

计算阴影面积(离散化+线段树) 

 

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <stdio.h>
 4 using namespace std;
 5 #define ll long long
 6 const int maxn = 204000;
 7 ll l[maxn], r[maxn], h[maxn], a[maxn*2], sum[maxn*2], cnt = 0;
 8 int n, num = 0, id = 1;
 9 bool lz[maxn*2];
10 void p(int node){
11     if(lz[node]){
12         sum[node<<1] = max(sum[node<<1], sum[node]);
13         sum[node<<1|1] = max(sum[node<<1|1], sum[node]);
14         lz[node<<1] = lz[node<<1|1] = true;
15         lz[node] = false;
16     }
17 }
18 void add(int lx, int rx, ll val, int lxx, int rxx, int node){
19     if(lx <= lxx && rxx <= rx){
20         sum[node] = max(sum[node], val);
21         lz[node] = true;
22         return ;
23     }
24     p(node);
25     int mid = (lxx+rxx) >> 1;
26     if(lx <= mid) add(lx, rx, val, lxx, mid, node<<1);
27     if(mid < rx) add(lx, rx, val, mid+1, rxx, node<<1|1);
28 }
29 void q(int lx, int rx, int node){
30     p(node);
31     if(rx == lx){
32         cnt += (a[id]-a[id-1])*sum[node];
33         id ++;
34         return;
35     }
36     int mid = (lx+rx) >> 1;
37     q(lx, mid, node<<1);
38     q(mid+1, rx, node<<1|1);
39 }
40 int main(){
41     scanf("%d", &n);
42     for(int i = 0; i < n; ++i){
43         scanf("%lld%lld%lld", &l[i], &r[i], &h[i]);
44         a[num++] = l[i], a[num++] = r[i];
45     }
46     sort(a, a+num);
47     num = unique(a, a+num) - a;
48     for(int i = 0; i < n; ++i){
49         int xx = lower_bound(a, a+num, l[i]) - a;
50         int yy = lower_bound(a, a+num, r[i]) - a;
51         add(xx+1, yy, h[i], 1, num, 1);
52     }
53     q(1, num, 1);
54     printf("%lld\n", cnt);
55     return 0;
56 }

 

-------------------------------------------------------------------

 

http://poj.org/problem?id=2528

几张海报(离散化+线段树)

 

 1 #include <iostream>
 2 #include <string.h>
 3 #include <stdio.h>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn = 10009;
 7 struct Node{
 8     int l, r;
 9 }T[maxn];
10 int a[maxn*6], sum[maxn*16], cnt;
11 bool vis[maxn*6];
12 void pd(int node){
13     if(sum[node] != -1){
14         sum[node<<1] = sum[node<<1|1] = sum[node];
15         sum[node] = -1;
16     }
17 }
18 void add(int l, int r, int val, int ll, int rr, int node){
19     if(l <= ll && rr <= r){
20         sum[node] = val;
21         return;
22     }
23     pd(node);
24     int mid = (ll+rr) >> 1;
25     if(l <= mid) add(l, r, val, ll, mid, node<<1);
26     if(mid < r) add(l, r, val, mid+1, rr, node<<1|1);
27 }
28 void find(int ll, int rr, int node){
29     if(sum[node] != -1){
30         if(!vis[sum[node]]) cnt ++, vis[sum[node]] = true;
31         return;
32     }
33     if(ll == rr) return;
34     int mid = (ll+rr) >> 1;
35     find(ll, mid, node<<1);
36     find(mid+1, rr, node<<1|1);
37 }
38 int main(){
39     int t, n;
40     scanf("%d", &t);
41     while(t--){
42         int num = 0;
43         scanf("%d", &n);
44         for(int i = 0; i < n; ++i){
45             scanf("%d%d", &T[i].l, &T[i].r);
46             a[num++] = T[i].l, a[num++] = T[i].r;
47         }
48         sort(a, a+num);
49         int m = unique(a, a+num) - a;
50         int xx = m;
51         for(int i = 1; i < m; ++i){
52             if(a[i]-a[i-1] > 1) a[xx++] = a[i-1]++;
53         }
54         sort(a, a+xx);
55         memset(sum, -1, sizeof(sum));
56         for(int i = 0; i < n; ++i){
57             int l = lower_bound(a, a+xx, T[i].l) - a;
58             int r = lower_bound(a, a+xx, T[i].r) - a;
59             add(l, r, i, 0, xx, 1);
60         }
61         memset(vis, false, sizeof(vis)), cnt = 0;
62         find(0, xx, 1);
63         printf("%d\n", cnt);
64     }
65     return 0;
66 }

 

 

 

-------------------------------------------------------------------

-------------------------------------------------------------------

-------------------------------------------------------------------

 

 

只有不断学习才能进步!

 

wenbao与线段树

原文:https://www.cnblogs.com/wenbao/p/5727790.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!