最近又开始刷线段树了。。还要改一下线段树的风格。
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 ", query_x(x, y, 1, n, 1)); 83 } 84 } 85 } 86 return 0; 87 }
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 ", 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 }
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 ", query(l, r, 1, n, 1)); 82 } 83 } 84 } 85 return 0; 86 }
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 ", ans); 85 } 86 } 87 } 88 return 0; 89 }
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 ", 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 ", ans[i]); 114 } 115 return 0; 116 }
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 ", 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 ", ans[i]); 205 } 206 return 0; 207 }
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 ", x); 102 update(x, x + L - 1, 0, 1, n, 1); 103 // printf("%d ", 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 }
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 ", query(L, R, 1, n, 1)); 128 } 129 } 130 return 0; 131 }