/** * 单点更新,区间查询 **/ ///hrb1752(单点替换,查询区间最大值及下标) ///代码: #define LSON l, m, rt<<1 #define RSON m+1, r, (rt<<1)|1 const int MAXN = 111111; int maxn[MAXN<<2]; int posn[MAXN<<2]; ///把当前节点的信息更新到父节点 void pushUp(int rt) { if (maxn[rt<<1] > maxn[rt<<1|1]) {///确保最大值相等时,rt节点保存的是rt<<1|1节点的信息 maxn[rt] = maxn[rt<<1]; posn[rt] = posn[rt<<1]; }else { maxn[rt] = maxn[rt<<1|1]; posn[rt] = posn[rt<<1|1]; } } ///建树 void build(int l, int r, int rt) { if (l == r) { scanf("%d", &maxn[rt]); posn[rt] = l; }else { int m = (l + r) >> 1; build(LSON); build(RSON); pushUp(rt); } } ///单点替换 void update(int p, int val, int l, int r, int rt) { if (l == r) { maxn[rt] = val; }else { int m = (l + r) >> 1; if (p <= m) { update(p, val, LSON); }else { update(p, val, RSON); } pushUp(rt); } } ///查询区间最大值及最大值的标号 int query(int L, int R, int l, int r, int rt, int *pos) {///pos存储page编号 if (L <= l && r <= R) { *pos = posn[rt]; return maxn[rt]; }else { int m = (l + r) >> 1; int ret1 = INT_MIN; int ret2 = INT_MIN; int pa, pb; int *pos1 = &pa; int *pos2 = &pb; if (L <= m) { ret1 = query(L, R, LSON, pos1); } if (R > m) { ret2 = query(L, R, RSON, pos2); } if (ret1 > ret2) { *pos = pa; ///最大值标号 }else { *pos = pb; ///最大值标号 ret1 = ret2; } return ret1; ///最大值 } } ///hdu1166(单点增减,查询区间和) ///代码: #define LSON l, m, rt<<1 #define RSON m+1, r, (rt<<1)|1 const int MAXN = 55555; int sum[MAXN<<2]; ///把当前节点的信息更新到父节点 void pushUp(int rt) { sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } ///建树 void build(int l, int r, int rt) { if (l == r) { scanf("%d", &sum[rt]); }else { int m = (l + r) >> 1; build(LSON); build(RSON); pushUp(rt); } } ///更新单点值(减去或加上一个值) void update(int p, int add, int l, int r, int rt) { if (l == r) { sum[rt] += add; }else { int m = (l + r) >> 1; if (p <= m) { update(p, add, LSON); }else { update(p, add, RSON); } pushUp(rt); } } ///查询区间和 int query(int L, int R, int l, int r, int rt) { if (L <= l && r <= R) { return sum[rt]; }else { int m = (l + r) >> 1; int ret = 0; if (L <= m) { ret += query(L, R, LSON); } if (R > m) { ret += query(L, R, RSON); } return ret; } } /** * 成段更新,区间查询 **/ ///hdu4027(成段开方,区间查询) /** * 题意:给出n(1<=n<=100000)个整数,m(1<=m<=100000)次操作, * 操作1:对区间[a,b]内的每个数开方,结果向下取整, * 操作2:查询区间[a,b]的总和。 * 分析:一个整数(>=1)经过多次开方后结果变为1, * 如果一个区间的所有整数都为1,则该区间不再需要更新。 **/ ///代码1: #define LSON l, m, rt<<1 #define RSON m+1, r, (rt<<1)|1 const int MAXN = 111111; __int64 sum[MAXN<<2]; ///把当前节点的信息更新到父节点 void pushUp(int rt) { sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } ///建树 void build(int l, int r, int rt) { if (l == r) { scanf("%I64d", &sum[rt]); }else { int m = (l + r) >> 1; build(LSON); build(RSON); pushUp(rt); } } ///成段更新(每个值开方) void update(int L, int R, int l, int r, int rt) { if (l == r) { ///更新叶子节点 sum[rt] = (__int64)sqrt((double)sum[rt]); }else { int m = (l + r) >> 1; ///(注意:此题数据中没有0,都为正整数,若有,则该判断条件不对,该解法不对) if (L <= m && ((__int64)(m-l+1) != sum[rt<<1])) {///判断是否要更新左子树 update(L, R, LSON); } ///(注意:此题数据中没有0,都为正整数,若有,则该判断条件不对,该解法不对) if (R > m && ((__int64)(r-m) != sum[rt<<1|1])) {///判断是否要更新右子树 update(L, R, RSON); } pushUp(rt); } } ///查询区间和 __int64 query(int L, int R, int l, int r, int rt) { if (L <= l && r <= R) { return sum[rt]; }else { int m = (l + r) >> 1; __int64 ret = 0; if (L <= m) { ret += query(L, R, LSON); } if (R > m) { ret += query(L, R, RSON); } return ret; } } ///代码2:数据中可以有0 #define LSON l, m, rt<<1 #define RSON m+1, r, (rt<<1)|1 const int MAXN = 111111; __int64 sum[MAXN<<2]; ///1为需要更新,0为不需要更新 __int64 flag[MAXN<<2];///是否要更新的标志(只要区间中有数据大于1,则该区间就要更新) ///把当前节点的信息更新到父节点 void pushUp(int rt) { sum[rt] = sum[rt<<1] + sum[rt<<1|1]; flag[rt] = flag[rt<<1] || flag[rt<<1|1]; } ///建树 void build(int l, int r, int rt) { if (l == r) { scanf("%I64d", &sum[rt]); flag[rt] = (sum[rt] <= 1 ? 0 : 1); }else { int m = (l + r) >> 1; build(LSON); build(RSON); pushUp(rt); } } ///成段更新(每个值开方) void update(int L, int R, int l, int r, int rt) { if (flag[rt] != 0) {///判断是否需要更新区间 if (l == r) { ///更新叶子节点 sum[rt] = (__int64)sqrt((double)sum[rt]); flag[rt] = (sum[rt] <= 1 ? 0 : 1); }else { int m = (l + r) >> 1; if (L <= m) {///更新左子树 update(L, R, LSON); } if (R > m) {///更新右子树 update(L, R, RSON); } pushUp(rt); } } } ///查询区间和 __int64 query(int L, int R, int l, int r, int rt) { if (L <= l && r <= R) { return sum[rt]; }else { int m = (l + r) >> 1; __int64 ret = 0; if (L <= m) { ret += query(L, R, LSON); } if (R > m) { ret += query(L, R, RSON); } return ret; } } ///pku3468(成段增减,区间查询,模板题) ///代码: #define LSON l, m, rt<<1 #define RSON m+1, r, (rt<<1)|1 const int MAXN = 111111; long long col[MAXN<<2]; ///lazy标记 long long sum[MAXN<<2]; ///把当前节点的信息更新到父节点 void pushUp(int rt) { sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } ///把当前节点的信息更新到子节点 void pushDown(int rt, int m) { if (col[rt]) { col[rt<<1] += col[rt]; col[rt<<1|1] += col[rt]; sum[rt<<1] += (m - (m >> 1)) * col[rt]; ///更新区间总和 sum[rt<<1|1] += (m >> 1) * col[rt]; ///更新区间总和 col[rt] = 0; } } ///建树 void build(int l, int r, int rt) { col[rt] = 0; if (l == r) { scanf("%lld", &sum[rt]); }else { int m = (l + r) >> 1; build(LSON); build(RSON); pushUp(rt); } } ///区间增减 void update(int L, int R, int val, int l, int r, int rt) { if (L <= l && r <= R) { col[rt] += val; sum[rt] += (r - l + 1) * val; ///更新区间总和 }else { pushDown(rt, r - l + 1); ///查看该节点是否被标记为lazy,是,则传递lazy标记给子节点 int m = (l + r) >> 1; if (L <= m) { update(L, R, val, LSON); } if (R > m) { update(L, R, val, RSON); } pushUp(rt); } } ///查询区间和 long long query(int L, int R, int l, int r, int rt) { if (L <= l && r <= R) { return sum[rt]; }else { pushDown(rt, r - l + 1); int m = (l + r) >> 1; long long ret = 0; if (L <= m) { ret += query(L, R, LSON); } if (R > m) { ret += query(L, R, RSON); } return ret; } } ///hdu1698(成段替换,查询整个区间的总和,总和存于根节点) ///代码: #define LSON l, m, rt<<1 #define RSON m+1, r, (rt<<1)|1 const int MAXN = 111111; int col[MAXN<<2]; ///lazy标记 int sum[MAXN<<2]; ///把当前节点的信息更新到父节点 void pushUp(int rt) { sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } ///把当前节点的信息更新到子节点 void pushDown(int rt, int m) { if (col[rt]) { col[rt<<1] = col[rt<<1|1] = col[rt]; sum[rt<<1] = (m - (m >> 1)) * col[rt]; sum[rt<<1|1] = (m >> 1) * col[rt]; col[rt] = 0; } } ///建树 void build(int l, int r, int rt) { col[rt] = 0; sum[rt] = 1; if (l != r) { int m = (l + r) >> 1; build(LSON); build(RSON); pushUp(rt); } } ///区间替换 void update(int L, int R, int val, int l, int r, int rt) { if (L <= l && r <= R) { col[rt] = val; sum[rt] = (r - l + 1) * val; }else { pushDown(rt, r - l + 1); ///查看该父节点是否被标记为lazy,是,则传递lazy标记给子节点 int m = (l + r) >> 1; if (L <= m) { update(L, R, val, LSON); } if (R > m) { update(L, R, val, RSON); } pushUp(rt); } } ///hdu3577(成段增加,查询区间最值) ///代码: #include<cstdio> #include<cstring> #include<climits> #include<algorithm> using namespace std; #define LSON l, m, rt<<1 #define RSON m+1, r, (rt<<1)|1 const int MAXN = 1111111; const int NN = 1000000; int col[MAXN<<2]; ///lazy标记 int maxn[MAXN<<2]; ///把当前节点的信息更新到父节点 void pushUp(int rt) { maxn[rt] = max(maxn[rt<<1], maxn[rt<<1|1]); } ///把当前节点的信息更新到子节点 void pushDown(int rt) { if (col[rt]) { col[rt<<1] += col[rt]; col[rt<<1|1] += col[rt]; maxn[rt<<1] += col[rt]; maxn[rt<<1|1] += col[rt]; col[rt] = 0; } } ///建树(树节点信息为0) void build(void) { memset(col, 0, sizeof(col)); memset(maxn, 0, sizeof(maxn)); } ///区间增值 void update(int L, int R, int val, int l, int r, int rt) { if (L <= l && r <= R) { col[rt] += val; maxn[rt] += val; }else { pushDown(rt); ///查看该节点是否被标记为lazy,是,则传递lazy标记给子节点 int m = (l + r) >> 1; if (L <= m) { update(L, R, val, LSON); } if (R > m) { update(L, R, val, RSON); } pushUp(rt); } } ///查询区间最值 int query(int L, int R, int l, int r, int rt) { if (L <= l && r <= R) { return maxn[rt]; }else { pushDown(rt); int m = (l + r) >> 1; int ret1 = INT_MIN; int ret2 = INT_MIN; if (L <= m) { ret1 = query(L, R, LSON); } if (R > m) { ret2 = query(L, R, RSON); } return (ret1 > ret2 ? ret1 : ret2); } } int main(void) { int T, n, k; scanf("%d", &T); for (int cas=1; cas<=T; ++cas) { scanf("%d%d", &k, &n); build(); int a, b; printf("Case %d:\n", cas); for (int i=1; i<=n; ++i) { scanf("%d%d", &a, &b); --b; ///注意(常识):到目的站时,人下车!所以,区间是[a, b-1] if (query(a, b, 1, NN, 1) < k) { update(a, b, 1, 1, NN, 1); printf("%d ", i); } } printf("\n\n"); } return 0; } ///hdu1556(成段增加,查询叶子节点最后的总值) ///代码: #define LSON l, m, rt<<1 #define RSON m+1, r, (rt<<1)|1 const int MAXN = 111111; int num[MAXN]; int col[MAXN<<2]; ///lazy标记 ///把当前节点的信息更新到子节点 void pushDown(int rt) { if (col[rt]) { col[rt<<1] += col[rt]; col[rt<<1|1] += col[rt]; col[rt] = 0; } } ///建树 void build(void) { memset(col, 0, sizeof(col)); } ///区间增值 void update(int L, int R, int val, int l, int r, int rt) { if (L <= l && r <= R) { col[rt] += val; ///累加延时标记 }else { pushDown(rt); ///查看该节点是否被标记为lazy,是,则传递lazy标记给子节点 int m = (l + r) >> 1; if (L <= m) { update(L, R, val, LSON); } if (R > m) { update(L, R, val, RSON); } } } void query(int l, int r, int rt) { if (l == r) { ///叶子节点总值 num[l] += col[rt]; }else { pushDown(rt); int m = (l + r) >> 1; query(LSON); query(RSON); } } int main(void) { int n; while (scanf("%d", &n) && n != 0) { build(); memset(num, 0, sizeof(num)); int a, b; for (int i=0; i<n; ++i) { scanf("%d%d", &a, &b); update(a, b, 1, 1, n, 1); } query(1, n, 1); for (int i=1; i<=n; ++i) { if (i != 1) { printf(" %d", num[i]); }else { printf("%d", num[i]); } } printf("\n"); } return 0; } ///pku2777(成段替换,查询区间总类数) ///代码: #define LSON l, m, rt<<1 #define RSON m+1, r, (rt<<1)|1 const int MAXN = 111111; const int SIZE = 31; bool hash[SIZE]; int num[MAXN<<2]; int cnt; void pushDown(int rt) { if (num[rt]) { num[rt<<1] = num[rt<<1|1] = num[rt]; num[rt] = 0; } } ///建树 void build(int l ,int r, int rt) { num[rt] = 1; if (l != r) { int m = (l + r) >> 1; build(LSON); build(RSON); } } ///区间替换 void update(int L, int R, int val, int l, int r, int rt) { if (num[rt] != val) { if (L <= l && r <= R) { num[rt] = val; }else { pushDown(rt); ///查看该节点是否被标记为lazy,是,则传递lazy标记给子节点 int m = (l + r) >> 1; if (L <= m) { update(L, R, val, LSON); } if (R > m) { update(L, R, val, RSON); } } } } void query(int L, int R, int l, int r, int rt) { if (num[rt]) { if (!hash[num[rt]]) { ++cnt; hash[num[rt]] = true; } }else { int m = (l + r) >> 1; if (L <= m) { query(L, R, LSON); } if (R > m) { query(L, R, RSON); } } }