wenbao与线段树
敌兵布阵
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 }
-------------------------------------------------------------------
-------------------------------------------------------------------
-------------------------------------------------------------------
只有不断学习才能进步!