树状数组。。
来源:互联网 发布:网络视频下载器 编辑:程序博客网 时间:2024/06/06 04:04
一维树状数组
hdu 1166
#include <iostream>#include <cstring>#include <cmath>#include <cstdlib>#include <cstdio>#include <algorithm>#include <queue>#include <stack>#define LL long long#define MAX 0x3f3f3f3f#define N (50000 + 5)using namespace std;int a[N], n;int lowbit(int x){ return x & (-x);}void add(int pi, int val){ while (pi <= n) { a[pi] += val; pi += lowbit(pi); //向上取整 }}int sum(int pi){ int ans = 0; while (pi > 0) { ans += a[pi]; pi -= lowbit(pi); } return ans;}int main(){ int T; scanf("%d", &T); for (int cas = 1; cas <= T; cas++) { scanf("%d", &n); printf("Case %d:\n", cas); memset(a, 0, sizeof(a)); for (int i = 1; i <= n; i++) { int t; scanf("%d", &t); add(i, t); } while(1) { char s1[10]; scanf("%s", s1); if(s1[0] == 'Q') { int s, t; scanf("%d%d", &s, &t); printf("%d\n", sum(t) - sum(s - 1)); } else if(s1[0] == 'A') { int pi, val; scanf("%d%d", &pi, &val); add(pi, val); } else if(s1[0] == 'S') { int pi, val; scanf("%d%d", &pi, &val); add(pi, -val); } else { break; } } }}
hdu 3972
题目大意:求0~n范围内两个相邻素数(差为2)的个数。
素数打表。。情况成立。。标记在第二个数上。。。
#include <iostream>#include <cstring>#include <cmath>#include <cstdlib>#include <cstdio>#include <algorithm>#include <queue>#include <stack>#include <string>#define LL long long#define MAX 0x3f3f3f3f#define N 100005#define M 32010using namespace std;bool not_prim[N];int d[N];int lowbit(int x){ return x & (-x);}void add(int pi){ while (pi < N) { d[pi] += 1; pi += lowbit(pi); }}int sum(int pi){ int ans = 0; while (pi > 0) { ans += d[pi]; pi -= lowbit(pi); } return ans;}void is_prime(){ memset(not_prim, 0, sizeof(not_prim)); for (int i = 2; i * i <= N; i++) { if (!not_prim[i]) { for (int j = i * i; j <= N; j += i) { not_prim[j] = 1; } } } for (int i = 5; i <= N; i += 2) { if (not_prim[i] == 0 && not_prim[i - 2] == 0) { // cout << 'i' << ' ' << i << endl; add(i); } }}int main(){ int n; memset(d, 0, sizeof(d)); is_prime(); while (~scanf("%d", &n) && n >= 0) { printf("%d\n", sum(n)); }}
hdu 1541
题目大意:求某星星左下方的个数。。(纵坐标按升序排列)
#include <iostream>#include <cstring>#include <cmath>#include <cstdlib>#include <cstdio>#include <algorithm>#include <queue>#include <stack>#include <string>#define LL long long#define MAX 0x3f3f3f3f#define N 15005#define M 32010using namespace std;int n, d[M], level[M];int lowbit(int x){ return x & (-x);}void add(int pi){ while (pi <= M) { d[pi] += 1; pi += lowbit(pi); }}int sum(int pi){ int ans = 0; while (pi > 0) { ans += d[pi]; pi -= lowbit(pi); } return ans;}int main(){ while (~scanf("%d", &n)) { int x, y; memset(d, 0, sizeof(d)); memset(level, 0, sizeof(level)); for (int i = 1; i <= n; i++) { scanf("%d%d", &x, &y); level[sum(++x)]++; add(x); } for (int i = 0; i < n; i++) { printf("%d\n", level[i]); } }}
hdu 2689
题目大意:将数据排列成升序。。求最少的排列次数。。(求逆序数)
全赋为0,输一个数则在该位置标记为1,统计比他小的输的个数
#include <iostream>#include <cstring>#include <cmath>#include <cstdlib>#include <cstdio>#include <algorithm>#include <queue>#include <stack>#include <string>#define LL __int64#define MAX 0x3f3f3f3f#define N 1005using namespace std;int n;int d[N];int lowbit(int x){ return x & (-x);}void add(int pi, int num){ while(pi <= n) { d[pi] += 1; pi += lowbit(pi); }}LL sum(int pi){ LL sum = 0; while(pi > 0) { sum += d[pi]; pi -= lowbit(pi); } return sum;}int main(){ while (~scanf("%d", &n)) { int t; memset(d, 0, sizeof(d)); int cnt = 0; for (int i = 1; i <= n; i++) { scanf("%d", &t); add(t, 1); cnt += i - sum(t); } cout << cnt << endl; }}
hdu 2838
题目大意:在2689的基础上求交换的最小代价;
开两个树状数组,分别记录其个数和代价。。。
#include <iostream>#include <cstring>#include <cmath>#include <cstdlib>#include <cstdio>#include <algorithm>#include <queue>#include <stack>#include <string>#define LL __int64#define MAX 0x3f3f3f3f#define N 100005using namespace std;int n;struct node{ int num; LL sum;}d[N];int lowbit(int x){ return x & (-x);}void add(int pi, int num){ while(pi <= 100000) { d[pi].num += 1; d[pi].sum += num; pi += lowbit(pi); }}int get_num(int pi)//得到比当前数小的数的个数{ int num = 0; while(pi > 0) { num += d[pi].num; pi -= lowbit(pi); } return num;}LL get_sum(int pi)//得到比当前数小的数的和{ LL sum = 0; while(pi > 0) { sum += d[pi].sum; pi -= lowbit(pi); } return sum;}int main(){ while(~scanf("%d", &n)) { memset(d, 0, sizeof(d)); int num; LL ans = 0; for(int i = 1; i <= n; i++) { scanf("%d", &num); add(num, num); int cnt = i - get_num(num);//有cnt的数比num大 if(cnt != 0) { ans += (LL)cnt * num + get_sum(100000) - get_sum(num); } } printf("%I64d\n", ans); } return 0;}
hdu 4046
hdu 2433
hdu 4312
二维树状数组
hdu 1559
求子矩阵的和最大
#include <iostream>#include <cstring>#include <cmath>#include <cstdlib>#include <cstdio>#include <algorithm>#include <queue>#include <stack>#include <string>#define LL __int64#define MAX 0x3f3f3f3f#define N 1005using namespace std;int n, m;int d[N][N];int lowbit(int x){ return x & (-x);}void add(int pi, int pj, int val){ for (int i = pi; i <= n; i += lowbit(i)) { for (int j = pj; j <= m; j += lowbit(j)) { d[i][j] += val; } }}int sum(int pi, int pj){ int ans = 0; for (int i = pi; i > 0; i -= lowbit(i)) { for (int j = pj; j > 0; j -= lowbit(j)) { ans += d[i][j]; } } return ans;}void init(){ for (int i = 0; i <= n; i++) { for (int j = 0; j <= m; j++) { d[i][j] = 0; } }}int main(){ int T; scanf("%d", &T); // memset(d, 0, sizeof(d)); while (T--) { int x, y, t; scanf("%d%d%d%d", &n, &m, &x, &y); init(); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { scanf("%d", &t); add(i, j, t); } } int temp, Max = 0; for (int i = 1; i + x - 1 <= n; i++) { for (int j = 1; j + y - 1 <= m; j++) { temp = sum(i + x - 1, j + y - 1) - sum(i - 1, j + y - 1) - sum(i + x - 1, j - 1) + sum(i - 1, j - 1); Max = max(Max, temp); } } printf("%d\n", Max); }}
hdu 1892
hdu 2852
hdu 2642
hdu 4311
hdu 2836
0 0
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- ServletConfig实现简单的登录操作
- 非root权限安装软件
- codevs1080线段树练习(线段树)
- 用Python写的hilbert曲线生成代码
- JAVA快捷键使用
- 树状数组。。
- HDU 1358 Period (kmp求周期)
- iOS、Mac代码规范
- 将Unity3D项目导出到Android工程中二次开发并实现之间的数据交互
- muleESB简介和安装(一)
- 一道题(5)
- Java基础(11):枚举类型
- stm32 mdk c++(error: #29: expected an expression)
- 【课本】学生信息管理