线段树

最近又开始刷线段树了。。还要改一下线段树的风格。

poj 2155 Matrix

二维线段树,区间更新,单点查询。。不会用新的代码写,用以前的风格写过了。。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 
 7 using namespace std;
 8 
 9 #define LL long long
10 #define eps 1e-8
11 #define inf 0x3f3f3f3f
12 #define MP make_pair
13 #define N 1010
14 #define M 200020
15 #pragma comment(linker, "/STACK:1024000000,1024000000")
16 #define Pi acos(-1.0)
17 #define mod 1000000007
18 #define lson l, mid, rt << 1
19 #define rson mid + 1, r, rt << 1 | 1
20 
21 
22 int sum[N<<2][N<<2], n;
23 void update_y(int ly, int ry, int i, int l, int r, int rt){
24     if(ly <= l && ry >= r){
25         sum[i][rt] ^= 1; return ;
26     }
27     int mid = (l + r) >> 1;
28     if(ly <= mid) update_y(ly, ry, i, lson);
29     if(ry > mid)  update_y(ly, ry, i, rson);
30 }
31 void update_x(int lx, int rx, int ly, int ry, int l, int r, int rt){
32     if(lx <= l && rx >= r){
33         update_y(ly, ry, rt, 1, n, 1);
34         return ;
35     }
36     int mid = (l + r) >> 1;
37     if(lx <= mid) update_x(lx, rx, ly, ry, lson);
38     if(rx > mid)  update_x(lx, rx, ly, ry, rson);
39 }
40 
41 
42 int query_y(int y, int i, int l, int r, int rt){
43     int ret = 0;
44     ret ^= sum[i][rt];
45     if(l == r)
46         return ret;
47     int mid = (l + r) >> 1;
48     if(y <= mid) ret ^= query_y(y, i, lson);
49     else ret ^= query_y(y, i, rson);
50     return ret;
51 }
52 int query_x(int x, int y, int l, int r, int rt){
53     int ret = 0;
54     ret ^= query_y(y, rt, 1, n, 1);
55     if(l == r)
56         return ret;
57     int mid = (l + r) >> 1;
58     if(x <= mid) ret ^= query_x(x, y, lson);
59     else ret ^= query_x(x, y, rson);
60     return ret;
61 }
62 int main(){
63     int cas, ok = 0;
64     scanf("%d", &cas);
65     while(cas--){
66         if(ok) puts("");
67         ok = 1;
68         int m;
69         scanf("%d%d", &n, &m);
70         memset(sum, 0, sizeof sum);
71         while(m--){
72             char ch[5];
73             scanf("%s", ch);
74             if(ch[0] == 'C'){
75                 int x, y, xx, yy;
76                 scanf("%d%d%d%d", &x, &y, &xx, &yy);
77                 update_x(x, xx, y, yy, 1, n, 1);
78             }
79             else{
80                 int x, y;
81                 scanf("%d%d", &x, &y);
82                 printf("%d\n", query_x(x, y, 1, n, 1));
83             }
84         }
85     }
86     return 0;
87 }
View Code

uva 11992 Fast Matrix Operations

矩阵不超过20行,开20棵线段树就可以了。

  1 #include<bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 #define LL long long
  6 #define eps 1e-8
  7 #define MP make_pair
  8 #define N 100010
  9 #define M 200020
 10 #pragma comment(linker, "/STACK:1024000000,1024000000")
 11 #define Pi acos(-1.0)
 12 #define mod 1000000007
 13 #define inf 0x3f3f3f3f
 14 #define ls (i << 1)
 15 #define rs (ls | 1)
 16 #define md ((ll + rr) >> 1)
 17 #define lson ll, md, ls
 18 #define rson md + 1, rr, rs
 19 
 20 int sum[22][N<<2], mi[22][N<<2], mx[22][N<<2], add[22][N<<2], val[22][N<<2];
 21 
 22 void push_down(int x, int i, int ll, int rr){
 23     if(val[x][i]){
 24         int v = val[x][i];
 25         val[x][ls] = val[x][rs] = v;
 26         sum[x][ls] = (md - ll + 1) * v, sum[x][rs] = (rr - md) * v;
 27         mi[x][ls] = mi[x][rs] = v;
 28         mx[x][ls] = mx[x][rs] = v;
 29         add[x][ls] = add[x][rs] = 0;
 30         val[x][i] = 0;
 31     }
 32     if(add[x][i]){
 33         int v = add[x][i];
 34         add[x][ls] += v, add[x][rs] += v;
 35         sum[x][ls] += (md - ll + 1) * v, sum[x][rs] += (rr - md) * v;
 36         mi[x][ls] += v,  mi[x][rs] += v;
 37         mx[x][ls] += v,  mx[x][rs] += v;
 38         add[x][i] = 0;
 39     }
 40 }
 41 void push_up(int x, int i, int ll, int rr){
 42     sum[x][i] = sum[x][ls] + sum[x][rs];
 43     mx[x][i] = max(mx[x][ls], mx[x][rs]);
 44     mi[x][i] = min(mi[x][ls], mi[x][rs]);
 45 }
 46 void add_x(int x, int l, int r, int v, int ll, int rr, int i){
 47     if(l == ll && r == rr){
 48         sum[x][i] += (r - l + 1) * v;
 49         add[x][i] += v;
 50         mi[x][i] += v, mx[x][i] += v;
 51         return ;
 52     }
 53     push_down(x, i, ll, rr);
 54     if(r <= md) add_x(x, l, r, v, lson);
 55     else if(l > md) add_x(x, l, r, v, rson);
 56     else
 57         add_x(x, l, md, v, lson), add_x(x, md + 1, r, v, rson);
 58     push_up(x, i, ll, rr);
 59 }
 60 void update(int x, int l, int r, int v, int ll, int rr, int i){
 61     if(l == ll && r == rr){
 62         sum[x][i] = (r - l + 1) * v;
 63         val[x][i] = v;
 64         mi[x][i] = mx[x][i] = v;
 65         add[x][i] = 0;
 66         return ;
 67     }
 68     push_down(x, i, ll, rr);
 69     if(r <= md) update(x, l, r, v, lson);
 70     else if(l > md) update(x, l, r, v, rson);
 71     else
 72         update(x, l, md, v, lson), update(x, md + 1, r, v, rson);
 73    push_up(x, i, ll, rr);
 74 }
 75 
 76 int ans_sum, ans_mi, ans_mx;
 77 void query(int x, int l, int r, int ll, int rr, int i){
 78     if(l == ll && r == rr){
 79         ans_sum += sum[x][i], ans_mi = min(ans_mi, mi[x][i]), ans_mx = max(ans_mx, mx[x][i]);
 80         return ;
 81     }
 82     push_down(x, i, ll, rr);
 83     if(r <= md) query(x, l, r, lson);
 84     else if(l > md) query(x, l, r, rson);
 85     else
 86         query(x, l, md, lson), query(x, md + 1, r, rson);
 87     push_up(x, i, ll, rr);
 88 }
 89 int main(){
 90     int n, m, q;
 91     while(scanf("%d%d%d", &n, &m, &q) != EOF){
 92         memset(sum, 0, sizeof sum);
 93         memset(mi, 0, sizeof mi);
 94         memset(mx, 0, sizeof mx);
 95         memset(add, 0, sizeof add);
 96         int x, xx, y, yy, op, v;
 97         while(q--){
 98             scanf("%d%d%d%d%d", &op, &x, &y, &xx, &yy);
 99             if(op == 3){
100                 ans_sum = 0, ans_mi = inf, ans_mx = 0;
101                 for(int i = x; i <= xx; ++i)
102                     query(i, y, yy, 1, m, 1);
103                 printf("%d %d %d\n", ans_sum, ans_mi, ans_mx);
104                 continue;
105             }
106             scanf("%d", &v);
107             if(op == 1){
108                 for(int i = x; i <= xx; ++i)
109                     add_x(i, y, yy, v, 1, m, 1);
110             }
111             if(op == 2){
112                 for(int i = x; i <= xx; ++i)
113                     update(i, y, yy, v, 1, m, 1);
114             }
115 
116         }
117     }
118     return 0;
119 }
View Code

hdu 3308 LCIS

求一段区间内的最大的 LCIS

做法:就是维护左端点,右端点,左右连续最大LCIS以及区间内最大LCIS,

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define LL long long
 6 #define eps 1e-8
 7 #define MP make_pair
 8 #define N 100010
 9 #define M 200020
10 #pragma comment(linker, "/STACK:1024000000,1024000000")
11 #define Pi acos(-1.0)
12 #define mod 1000000007
13 #define inf 0x3f3f3f3f
14 #define ls (i << 1)
15 #define rs (ls | 1)
16 #define md ((ll + rr) >> 1)
17 #define lson ll, md, ls
18 #define rson md + 1, rr, rs
19 
20 int mxL[N<<2], mxR[N<<2], sumL[N<<2], sumR[N<<2], sum[N<<2];
21 void f(int i, int v){
22     mxL[i] = mxR[i] = v;
23     sumL[i] = sumR[i] = sum[i] = 1;
24 }
25 void push_up(int i, int ll, int rr){
26     mxL[i] = mxL[ls], mxR[i] = mxR[rs];
27     sumL[i] = sumL[ls], sumR[i] = sumR[rs];
28     sum[i] = max(sum[ls], sum[rs]);
29     if(mxR[ls] < mxL[rs]){
30         sum[i] = max(sum[i], sumR[ls] + sumL[rs]);
31         if(sumL[ls] == md - ll + 1)
32             sumL[i] += sumL[rs];
33         if(sumR[rs] == rr - md)
34             sumR[i] += sumR[ls];
35     }
36 }
37 void build(int ll, int rr, int i){
38     if(ll == rr){
39         int v; scanf("%d", &v);
40         f(i, v);
41         return ;
42     }
43     build(lson), build(rson);
44     push_up(i, ll, rr);
45 }
46 void update(int p, int v, int ll, int rr, int i){
47     if(ll == rr){
48         f(i, v); return ;
49     }
50     if(p <= md) update(p, v, lson);
51     else update(p, v, rson);
52     push_up(i, ll, rr);
53 }
54 int query(int l, int r, int ll, int rr, int i){
55     if(l == ll && r == rr){
56         return sum[i];
57     }
58     if(r <= md) return query(l, r, lson);
59     if(l > md) return query(l, r, rson);
60     int ret1 = query(l, md, lson), ret2 = query(md + 1, r, rson), ret = 0;
61     if(mxR[ls] < mxL[rs])
62         ret = min(sumR[ls], md - l + 1) + min(sumL[rs], r - md);
63     return max(ret, max(ret1, ret2));
64 }
65 int main(){
66     //freopen("tt.txt", "r", stdin);
67     int cas, n, m;
68     scanf("%d", &cas);
69     while(cas--){
70         scanf("%d%d", &n, &m);
71         build(1, n, 1);
72         char ch[5]; int l, r;
73         while(m--){
74             scanf("%s%d%d", ch, &l, &r);
75             if(ch[0] == 'U'){
76                 l++;
77                 update(l, r, 1, n, 1);
78             }
79             else {
80                 l++, r++;
81                 printf("%d\n", query(l, r, 1, n, 1));
82             }
83         }
84     }
85     return 0;
86 }
View Code

poj 2777 Count Color

询问一段区间内有多少种不同的颜色。

做法:不超过30种颜色,那么用二进制表示该区间是否存在该种颜色

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<cstdio>
 5 #include<algorithm>
 6 
 7 using namespace std;
 8 
 9 #define LL long long
10 #define eps 1e-8
11 #define MP make_pair
12 #define N 100010
13 #define M 200020
14 #pragma comment(linker, "/STACK:1024000000,1024000000")
15 #define Pi acos(-1.0)
16 #define mod 1000000007
17 #define inf 0x3f3f3f3f
18 #define ls (i << 1)
19 #define rs (ls | 1)
20 #define md ((ll + rr) >> 1)
21 #define lson ll, md, ls
22 #define rson md + 1, rr, rs
23 
24 LL sum[N<<2], down[N<<2];
25 void push_down(int i){
26     if(down[i]){
27         down[ls] = down[i], down[rs] = down[i];
28         sum[ls] = down[i], sum[rs] = down[i];
29         down[i] = 0;
30     }
31 }
32 void push_up(int i){
33     sum[i] = (sum[ls] | sum[rs]);
34 }
35 void build(int ll, int rr, int i){
36     sum[i] = 1, down[i] = 0;
37     if(ll == rr) return ;
38     build(lson), build(rson);
39 }
40 void update(int l, int r, LL v, int ll, int rr, int i){
41     if(l == ll && r == rr){
42         sum[i] = v;
43         down[i] = v;
44         return ;
45     }
46     push_down(i);
47     if(r <= md) update(l, r, v, lson);
48     else if(l > md) update(l, r, v, rson);
49     else
50         update(l, md, v, lson), update(md + 1, r, v, rson);
51     push_up(i);
52 }
53 LL query(int l, int r, int ll, int rr, int i){
54     if(l == ll && r == rr)
55         return sum[i];
56     push_down(i);
57     if(r <= md) return query(l, r, lson);
58     if(l > md) return query(l, r, rson);
59     int ret1 = query(l, md, lson), ret2 = query(md + 1, r, rson);
60     push_up(i);
61     return (ret1 | ret2);
62 }
63 int main(){
64     int n, c, m;
65     while(scanf("%d%d%d", &n, &c, &m) != EOF){
66         build(1, n, 1);
67         char ch[5];
68         int l, r, c;
69         while(m--){
70             scanf("%s%d%d", ch, &l, &r);
71             if(l > r) swap(l, r);
72             if(ch[0] == 'C'){
73                 scanf("%d", &c);
74                 c--;
75                 update(l, r, (1LL<<c), 1, n, 1);
76             }
77             else{
78                 LL tot = query(l, r, 1, n, 1);
79                 int ans = 0;
80                 while(tot){
81                     if(tot & 1) ans++;
82                     tot >>= 1;
83                 }
84                 printf("%d\n", ans);
85             }
86         }
87     }
88     return 0;
89 }
View Code

hdu 5381 The sum of gcd

You have an array A,the length of A is n
Let f(l,r)=∑(r, i=l)∑ (r,j=i)gcd(ai,ai+1....aj)

做法:离线处理。。按照r排序,i从1到n,由于每个数ai的gcd最多有log(ai)个。用线段树区间更新,然后区间查询(l, r),复杂度nlognlogn。。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <queue>
  7 using namespace std;
  8 
  9 #define LL long long
 10 #define eps 1e-8
 11 #define inf 0x3f3f3f3f
 12 #define MP make_pair
 13 #define N 10020
 14 #define M 200020
 15 #pragma comment(linker, "/STACK:1024000000,1024000000")
 16 #define Pi acos(-1.0)
 17 #define mod 258280327
 18 #define ls (i << 1)
 19 #define rs (ls | 1)
 20 #define md ((ll + rr) >> 1)
 21 #define lson ll, md, ls
 22 #define rson md + 1, rr, rs
 23 
 24 struct node{
 25     int l, r, id;
 26     bool operator < (const node &b) const{
 27         return r < b.r;
 28     }
 29 }p[N];
 30 
 31 LL sum[N<<2], down[N<<2];
 32 
 33 void push_down(int i, int ll, int rr){
 34     if(down[i]){
 35         sum[ls] += 1LL * (md - ll + 1) * down[i];
 36         sum[rs] += 1LL * (rr - md) * down[i];
 37         down[ls] += down[i], down[rs] += down[i];
 38         down[i] = 0;
 39     }
 40 }
 41 void push_up(int i){
 42     sum[i] = sum[ls] + sum[rs];
 43 }
 44 void update(int l, int r, int v, int ll, int rr, int i){
 45     if(l == ll && r == rr){
 46         sum[i] += 1LL * (r - l + 1) * v;
 47         down[i] += v;
 48         return ;
 49     }
 50     push_down(i, ll, rr);
 51     if(r <= md) update(l, r, v, lson);
 52     else if(l > md) update(l, r, v, rson);
 53     else
 54         update(l, md, v, lson), update(md + 1, r, v, rson);
 55     push_up(i);
 56 }
 57 LL query(int l, int r, int ll, int rr, int i){
 58     if(l == ll && r == rr)
 59         return sum[i];
 60     LL ret = 0;
 61     push_down(i, ll, rr);
 62     if(r <= md) ret = query(l, r, lson);
 63     else if(l > md) ret = query(l, r, rson);
 64     else ret = query(l, md, lson) + query(md + 1, r, rson);
 65     push_up(i);
 66     return ret;
 67 }
 68 int gcd(int x, int y){
 69     return y == 0 ? x : gcd(y, x % y);
 70 }
 71 
 72 int a[N], val[N], nxt[N];
 73 LL ans[N];
 74 void debug(int i){
 75     printf("%lld\n", sum[i]);
 76 }
 77 int main(){
 78     //freopen("tt.txt", "r", stdin);
 79     int cas;
 80     scanf("%d", &cas);
 81     while(cas--){
 82         int n, m;
 83         scanf("%d", &n);
 84         for(int i = 1; i <= n; ++i)
 85             scanf("%d", &a[i]);
 86         scanf("%d", &m);
 87         for(int i = 0; i < m; ++i){
 88             scanf("%d%d", &p[i].l, &p[i].r);
 89             p[i].id = i;
 90         }
 91         sort(p, p + m);
 92         memset(sum, 0, sizeof sum);
 93         memset(down, 0, sizeof down);
 94         update(1, 1, a[1], 1, n, 1);
 95         val[1] = a[1], nxt[1] = 1;
 96         int k = 0;
 97         for(int i = 2; i <= n; ++i){
 98             int j = i;
 99             val[i] = a[i], nxt[i] = i;
100             while(j > 0){
101                 val[j] = gcd(val[j], a[i]);
102                 while(nxt[j] > 1 && gcd(val[j], val[nxt[j]-1]) == val[j])
103                     nxt[j] = nxt[nxt[j]-1];
104                 update(nxt[j], j, val[j], 1, n, 1);
105                 j = nxt[j] - 1;
106             }
107             while(k < m && p[k].r == i){
108                 ans[p[k].id] = query(p[k].l, p[k].r, 1, n, 1);
109                 ++k;
110             }
111         }
112         for(int i = 0; i < m; ++i)
113             printf("%lld\n", ans[i]);
114     }
115     return 0;
116 }
View Code

 hdu 5390 tree

trie树+线段树。处理dfs序,离线操作,在线段树每个节点做这些操作。直接在线做会爆空间。

b[N*20]要开20倍,不能开10倍,因为线段树logn层 > 10

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <queue>
  7 using namespace std;
  8 
  9 #define LL long long
 10 #define eps 1e-6
 11 #define inf 0x3f3f3f3f
 12 #define MP make_pair
 13 #define N 100020
 14 #define M 1000020
 15 #pragma comment(linker, "/STACK:1024000000,1024000000")
 16 #define Pi acos(-1.0)
 17 #define mod 258280327
 18 #define ls (i << 1)
 19 #define rs (ls | 1)
 20 #define md ((ll + rr) >> 1)
 21 #define lson ll, md, ls
 22 #define rson md + 1, rr, rs
 23 
 24 
 25 int readint() {
 26     char c;
 27     while((c = getchar()) && !(c >= '0' && c <= '9') && c != '-');
 28 
 29     int ret = c - '0', sgn = 0;
 30     if(c == '-') ret = 0, sgn = 1;
 31     while((c = getchar()) && c >= '0' && c <= '9')
 32         ret = ret * 10 + c - '0';
 33     if(sgn) ret = -ret;
 34     return ret;
 35 }
 36 
 37 
 38 int fst[N], nxt[N], vv[N], e, n, m;
 39 void init(){
 40     for(int i = 1; i <= n; ++i) fst[i] = -1;
 41     e = 0;
 42 }
 43 void add(int u, int v){
 44     vv[e] = v, nxt[e] = fst[u], fst[u] = e++;
 45 }
 46 
 47 int dc, in[N], out[N];
 48 void dfs(int u){
 49     in[u] = ++dc;
 50     for(int i = fst[u]; ~i; i = nxt[i]){
 51         int v = vv[i];
 52         dfs(v);
 53     }
 54     out[u] = dc;
 55 }
 56 
 57 struct node{
 58     int L, R, op, val;
 59     node(){}
 60     node(int _op, int _L, int _R, int _val){
 61         op = _op, L = _L, R = _R, val = _val;
 62     }
 63 }b[N*20];
 64 
 65 struct Trie{
 66     int ch[N*33][2], cnt[N*33], tot;
 67     void init(){
 68         ch[0][0] = ch[0][1] = -1;
 69         tot = 0;
 70         cnt[0] = 0;
 71     }
 72     void insert(int x, int v){
 73         int a[33];
 74         for(int i = 0; i < 32; ++i)
 75             a[i] = (x >> i) & 1;
 76         int t = 0;
 77         for(int i = 31; i >= 0; --i){
 78             int c = a[i];
 79             if(ch[t][c] == -1){
 80                 ch[t][c] = ++tot;
 81                 ch[tot][0] = ch[tot][1] = -1;
 82                 cnt[tot] = 0;
 83             }
 84             t = ch[t][c];
 85             cnt[t] += v;
 86         }
 87     }
 88     int query(int x){
 89         if(tot == 0) return 0;
 90         int a[33];
 91         for(int i = 0; i < 32; ++i)
 92             a[i] = (x >> i) & 1;
 93         int t = 0, ret = 0;
 94         for(int i = 31; i >= 0; --i){
 95             int c = a[i];
 96             if(ch[t][c^1] == -1 || cnt[ch[t][c^1]] == 0){
 97                 if(ch[t][c] == -1 || cnt[ch[t][c]] == 0) return 0;
 98                 t = ch[t][c];
 99             }
100             else t = ch[t][c^1], ret += 1 << i;
101         }
102         return ret;
103     }
104 }trie;
105 
106 int val[N], ans[N], cnt;
107 
108 void solve(int l, int r, int ll, int rr){
109     if(l > r) return ;
110     if(ll == rr){
111         trie.init();
112         for(int i = l; i <= r; ++i){
113             if(b[i].op == 0)
114                 trie.insert(b[i].val, 1);
115             else if(b[i].op == 2)
116                 trie.insert(b[i].val, -1);
117             else
118                 ans[b[i].R] = max(ans[b[i].R], trie.query(b[i].val));
119         }
120         return ;
121     }
122     trie.init();
123     for(int i = l; i <= r; ++i){
124         if(b[i].op == 0){
125             if(b[i].L == ll && b[i].R == rr)
126                 trie.insert(b[i].val, 1);
127         }
128         else if(b[i].op == 2){
129             if(b[i].L == ll && b[i].R == rr)
130                 trie.insert(b[i].val, -1);
131         }
132         else
133             ans[b[i].R] = max(ans[b[i].R], trie.query(b[i].val));
134     }
135     int t = cnt;
136     for(int i = l; i <= r; ++i){
137         if(b[i].op == 0 || b[i].op == 2){
138             if(b[i].L == ll && b[i].R == rr) continue;
139             if(b[i].L > md) continue;
140             b[++cnt] = b[i];
141             if(b[i].R > md) b[cnt].R = md;
142         }
143         else{
144             if(b[i].L <= md) b[++cnt] = b[i];
145         }
146     }
147     solve(t + 1, cnt, ll, md);
148     cnt = t;
149     for(int i = l; i <= r; ++i){
150         if(b[i].op == 0 || b[i].op == 2){
151             if(b[i].L == ll && b[i].R == rr) continue;
152             if(b[i].R <= md) continue;
153             b[++cnt] = b[i];
154             if(b[i].L <= md) b[cnt].L = md + 1;
155         }
156         else{
157             if(b[i].L > md) b[++cnt] = b[i];
158         }
159     }
160     solve(t + 1, cnt, md + 1, rr);
161     cnt = t;
162 }
163 void debug(){
164     for(int i = 1; i <= cnt; ++i){
165         printf("%d %d %d %d\n", b[i].op, b[i].L, b[i].R, b[i].val);
166     }
167 }
168 int main(){
169    // freopen("1011.in", "r", stdin);
170     int cas;
171     cas = readint();
172     while(cas--){
173         n = readint(), m = readint();
174         init();
175         for(int i = 2; i <= n; ++i){
176             int u;
177             u = readint();
178             add(u, i);
179         }
180         dc = cnt = 0;
181         dfs(1);
182         for(int i = 1; i <= n; ++i){
183             val[i] = readint();
184             b[++cnt] = node(0, in[i], out[i], val[i]);
185         }
186         int tot = 0;
187         while(m--){
188             int op, u, v;
189             op = readint();
190             if(op == 0){
191                 u = readint(), v = readint();
192                 b[++cnt] = node(2, in[u], out[u], val[u]);
193                 val[u] = v;
194                 b[++cnt] = node(0, in[u], out[u], v);
195             }
196             else{
197                 u = readint();
198                 b[++cnt] = node(1, in[u], ++tot, val[u]);
199             }
200         }
201         for(int i = 1; i <= tot; ++i) ans[i] = 0;
202         solve(1, cnt, 1, n);
203         for(int i = 1; i <= tot; ++i)
204             printf("%d\n", ans[i]);
205     }
206     return 0;
207 }
View Code

 poj 3667 Hotel

区间合并。。好像很难,细心。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <queue>
  7 #include <stack>
  8 
  9 using namespace std;
 10 
 11 #define LL long long
 12 #define eps 1e-6
 13 #define inf 0x3f3f3f3f
 14 #define MP make_pair
 15 #define N 100020
 16 #define M 1000020
 17 #pragma comment(linker, "/STACK:1024000000,1024000000")
 18 #define Pi acos(-1.0)
 19 #define mod 258280327
 20 #define ls (i << 1)
 21 #define rs (ls | 1)
 22 #define md ((ll + rr) >> 1)
 23 #define lson ll, md, ls
 24 #define rson md + 1, rr, rs
 25 
 26 int sumL[N<<2], sumR[N<<2], sum[N<<2], down[N<<2];
 27 void build(int ll, int rr, int i){
 28     down[i] = -1;
 29     sumL[i] = sumR[i] = sum[i] = rr - ll + 1;
 30     if(ll == rr) return ;
 31     build(lson), build(rson);
 32 }
 33 
 34 void f(int i, int u, int v){
 35     sumL[i] = sumR[i] = sum[i] = v;
 36     down[i] = u;
 37 }
 38 void push_down(int i, int ll, int rr){
 39     if(down[i] == 1){
 40         f(ls, 1, md - ll + 1);
 41         f(rs, 1, rr - md);
 42         down[i] = -1;
 43     }
 44     if(down[i] == 0){
 45         f(ls, 0, 0);
 46         f(rs, 0, 0);
 47         down[i] = -1;
 48     }
 49 }
 50 void push_up(int i, int ll, int rr){
 51     sumL[i] = sumL[ls], sumR[i] = sumR[rs];
 52     sum[i] = max(sum[ls], sum[rs]);
 53     sum[i] = max(sum[i], sumR[ls] + sumL[rs]);
 54     if(sumL[ls] == md - ll + 1)
 55         sumL[i] += sumL[rs];
 56     if(sumR[rs] == rr - md)
 57         sumR[i] += sumR[ls];
 58 }
 59 void update(int l, int r, int v, int ll, int rr, int i){
 60     if(l == ll && r == rr){
 61         if(v == 1)
 62             f(i, 1, rr - ll + 1);
 63         else
 64             f(i, 0, 0);
 65         return ;
 66     }
 67     push_down(i, ll, rr);
 68     if(r <= md) update(l, r, v, lson);
 69     else if(l > md) update(l, r, v, rson);
 70     else update(l, md, v, lson), update(md + 1, r, v, rson);
 71     push_up(i, ll, rr);
 72 }
 73 int query(int p, int ll, int rr, int i){
 74     if(ll == rr){
 75         return sum[i];
 76     }
 77     push_down(i, ll, rr);
 78     int ret;
 79     if(sum[ls] >= p)
 80         ret = query(p, lson);
 81     else if(sumR[ls] + sumL[rs] >= p)
 82         ret = md - sumR[ls] + 1;
 83     else
 84         ret = query(p, rson);
 85     push_up(i, ll, rr);
 86     return ret;
 87 }
 88 int main(){
 89     //freopen("tt.txt", "r", stdin);
 90     int n, m;
 91     while(scanf("%d%d", &n, &m) != EOF){
 92         build(1, n, 1);
 93         int op, L, R;
 94         while(m--){
 95             scanf("%d%d", &op, &L);
 96             if(op == 1){
 97                 if(sum[1] < L){
 98                     puts("0"); continue;
 99                 }
100                 int x = query(L, 1, n, 1);
101                 printf("%d\n", x);
102                 update(x, x + L - 1, 0, 1, n, 1);
103                // printf("%d\n", sum[1]);
104             }
105             else{
106                 scanf("%d", &R);
107                 update(L, L + R - 1, 1, 1, n, 1);
108             }
109         }
110     }
111     return 0;
112 }
View Code

 uva 12436 Rip Van Winkle's Code

从昨晚wa到早上。。题目的意思就不说了。。

开6个数组。t1,t2表示第一种和第二种操作区间内,最左边的数加的值。c1,c2表示第一种和第二种操作加的次数(等差数列,公差就是次数)。最坑爹的是cover的操作,在push_down里是if(cov[i]){}然后才push_down的,如果把区间内的数变为0就跪了。。所以开多一个数组。。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <queue>
  7 #include <stack>
  8 
  9 using namespace std;
 10 
 11 #define LL long long
 12 #define eps 1e-6
 13 #define inf 0x3f3f3f3f
 14 #define MP make_pair
 15 #define N 250020
 16 #define M 1000020
 17 #pragma comment(linker, "/STACK:1024000000,1024000000")
 18 #define Pi acos(-1.0)
 19 #define ls (i << 1)
 20 #define rs (ls | 1)
 21 #define md ((ll + rr) >> 1)
 22 #define lson ll, md, ls
 23 #define rson md + 1, rr, rs
 24 
 25 LL sum[N<<2], cov[N<<2], t1[N<<2], t2[N<<2], c1[N<<2], c2[N<<2], down[N<<2];
 26 void build(int ll, int rr, int i){
 27     sum[i] = cov[i] = t1[i] = t2[i] = c1[i] = c2[i] = down[i] = 0;
 28     if(ll == rr) return ;
 29     build(lson), build(rson);
 30 }
 31 void push_down(int i, int ll, int rr){
 32     if(down[i]){
 33         down[ls] = down[rs] = 1;
 34         cov[ls] = cov[rs] = cov[i];
 35         sum[ls] = cov[i] * (md - ll + 1);
 36         sum[rs] = cov[i] * (rr - md);
 37         t1[ls] = t1[rs] = t2[ls] = t2[rs] = 0;
 38         c1[ls] = c1[rs] = c2[ls] = c2[rs] = 0;
 39         cov[i] = 0;
 40         down[i] = 0;
 41     }
 42     if(t1[i]){
 43         c1[ls] += c1[i], c1[rs] += c1[i];
 44         t1[ls] += t1[i], t1[rs] += (md - ll + 1) * c1[i] + t1[i];
 45         sum[ls] += (t1[i] + t1[i] + (md - ll) * c1[i]) * (md -ll + 1) / 2;
 46         sum[rs] += ((md - ll + 1) * c1[i] + t1[i] + t1[i] + (rr - ll) * c1[i]) * (rr - md) / 2;
 47         t1[i] = c1[i] = 0;
 48     }
 49     if(t2[i]){
 50         c2[ls] += c2[i], c2[rs] += c2[i];
 51         t2[ls] += t2[i], t2[rs] += t2[i] - (md - ll + 1) * c2[i] ;
 52         sum[ls] += (t2[i] + t2[i] - (md - ll) * c2[i]) * (md - ll + 1) / 2;
 53         sum[rs] += (t2[i] - (md - ll + 1) * c2[i] + t2[i] - (rr - ll) * c2[i]) * (rr - md) / 2;
 54         t2[i] = c2[i] = 0;
 55     }
 56 }
 57 void push_up(int i){
 58     sum[i] = sum[ls] + sum[rs];
 59 }
 60 void update(int l, int r, LL v, int op, int ll, int rr, int i){
 61     if(l == ll && r == rr){
 62         if(op == 1){
 63             sum[i] += 1LL * (v + rr - ll + v) * (rr - ll + 1) / 2;
 64             t1[i] += v;
 65             c1[i]++;
 66         }
 67         else if(op == 2){
 68             sum[i] += 1LL * (v - rr + ll + v) * (rr - ll + 1) / 2;
 69             t2[i] += v;
 70             c2[i]++;
 71         }
 72         else if(op == 3){
 73             sum[i] = 1LL * v * (rr - ll + 1);
 74             cov[i] = v;
 75             down[i] = 1;
 76             t1[i] = t2[i] = c1[i] = c2[i] = 0;
 77         }
 78         return ;
 79     }
 80     push_down(i, ll, rr);
 81     if(r <= md) update(l, r, v, op, lson);
 82     else if(l > md) update(l, r, v, op, rson);
 83     else{
 84         if(op == 1){
 85             update(l, md, v, op, lson);
 86             int val = v + (md - l + 1);
 87             update(md + 1, r, val, op, rson);
 88         }
 89         else if(op == 2){
 90             update(l, md, v, op, lson);
 91             int val = v - (md - l + 1);
 92             update(md + 1, r, val, op, rson);
 93         }
 94         else update(l, md, v, op, lson), update(md + 1, r, v, op, rson);
 95     }
 96     push_up(i);
 97 }
 98 LL query(int l, int r, int ll, int rr, int i){
 99     if(l == ll && r == rr)
100         return sum[i];
101     push_down(i, ll, rr);
102     LL ret = 0;
103     if(r <= md) ret = query(l, r, lson);
104     else if(l > md) ret = query(l, r, rson);
105     else ret = query(l, md, lson) + query(md + 1, r, rson);
106     push_up(i);
107     return ret;
108 }
109 int main(){
110     int m, n = 250000;
111     while(scanf("%d", &m) != EOF){
112         build(1, n, 1);
113         char s[5];
114         int L, R, c;
115         while(m--){
116             scanf("%s", s);
117             scanf("%d%d", &L, &R);
118             if(s[0] == 'A'){
119                 update(L, R, 1, 1, 1, n, 1);
120             }
121             else if(s[0] == 'B')
122                 update(L, R, R - L + 1, 2, 1, n, 1);
123             else if(s[0] == 'C'){
124                 scanf("%d", &c);
125                 update(L, R, c, 3, 1, n, 1);
126             }
127             else printf("%lld\n", query(L, R, 1, n, 1));
128         }
129     }
130     return 0;
131 }
View Code

 

posted @ 2015-08-15 13:11  L__J  阅读(211)  评论(0编辑  收藏  举报