#include<bits/stdc++.h> usingnamespace std; int n, a[1010101]; intlowbit(int x){ return x & -x; } voidupdate(int p, int u){ for (int i = p; i <= n; i += lowbit(i)) a[i] += u; } intquery(int x){ int res = 0; for (int i = x; i > 0; i -= lowbit(i)) res += a[i]; return res; } intmain(){ int m; scanf("%d%d",&n,&m); for (int i = 1; i <= n; i++) { int x; scanf("%d",&x); update(i, x); } while (m--) { int k, x, y; scanf("%d%d%d",&k,&x,&y); if (k == 0) { printf("%d\n", query(y) - query(x - 1)); }else{ update(x,y); } } }
int a[1510101]; int tr[1501010], n; intlowbit(int x){ return x & -x; } voidupdate(int x, int u){ for (int i = x; i <= 32010; i += lowbit(i)) tr[i] += u;//x的上界不是n! } intquery(int l){ int res = 0; for (int i = l; i > 0; i -= lowbit(i)) res += tr[i]; return res; } int x, y; intmain(){ cin >> n; for (int i = 1; i <= n; i++) { scanf("%d%d",&x,&y); //树状数组必须从1开始!所以y+1! printf("%d\n",query(x + 1)); //这里星星本身并不算在内,所以要先进行查询,然后再update update(x + 1, 1); } }
/* 首先这个题你已经知道是个树状数组了,而且强制在线。然后呢,如果在种树的时候一个一个update的话就很浪费对吧,而且会T 那我们仅记录种树的L,R,如果当前我询问的区间的R大于这个种树的L而且这个L>=询问的L,那就代表我当前询问的区间内包含(不一定完全包含)该种树的区间。 那就代表这个种树区间一定是答案的一种,然后我们统计有多少个这样的区间即可。 先算有多少个区间的L小于当前我种树的R,然后算出来的数再减去有多少个区间的L小于询问的L即可。 */ #include<bits/stdc++.h> usingnamespace std; int n, k, x, y, tl[101010], tr[101010], m; intlowbit(int x){ return x & -x; } voidupdatel(int p, int u){ for (int i = p; i <= n; i += lowbit(i)) tl[i] += u; } voidupdater(int p, int u){ for (int i = p; i <= n; i += lowbit(i)) tr[i] += u; } intqueryl(int p){ int res = 0; for (int i = p; i > 0; i -= lowbit(i)) res += tl[i]; return res; } intqueryr(int p){ int res = 0; for (int i = p; i > 0; i -= lowbit(i)) res += tr[i]; return res; }
intmain(){ cin >> n >> m; for (int i = 1; i <= m; i++) { scanf("%d%d%d",&k,&x,&y); if (k == 1) { updatel(x, 1); updater(y, 1); } else { cout << queryl(y)/*查左端点小于y*/ - queryr(x - 1)/*查右端点小于x,因为右端点等于x也算在区间内,所以要减1*/ << "\n"; } } }
/* 阅读理解+水题一道 首先校长在m节车厢就是查询1-m的总人数 有人上下车就是update,下车就是update一个负数 几节车厢就是几个值来建树状数组 */ #include<bits/stdc++.h> usingnamespace std; int n, m, tr[10101000]; intlowbit(int x){ return x & -x; } voidupdate(int p, int u){ for (int i = p; i <= n; i += lowbit(i)) tr[i] += u; } intquery(int p){ int res = 0; for (int i = p; i > 0; i -= lowbit(i)) res += tr[i]; return res; } intmain(){ cin >> n >> m; for (int i = 1; i <= m; i++) { char op[2]; int l, r; scanf("%s%d", &op, &l);//可恶只能输入字符数组 if (op[0] == 'A') { printf("%d\n", query(l)); } elseif (op[0] == 'B') { scanf("%d", &r); update(l, r); } else { scanf("%d", &r); update(l, -r); } } }
/* 有点难度,需要差分,首先我们需要注意到为什么它不问区间求和而是单点查询?有猫腻 我们构造差分数组,再在差分数组的基础上构造树状数组,那么我们先把原数组做差分, 这时,查询点x的值就是把1-x的值都加起来,不就是query(x)吗? 对于区间加减操作,我们就采用差分的区间操作的方法,把tr[l]++,tr[r+1]--,就完结了~ */ #include<bits/stdc++.h> usingnamespace std; int n, m, x, y, k, op, tr[1010101]; intlowbit(int x){ return x & -x; } voidupdate(int p, int u){ for (int i = p; i <= n; i += lowbit(i)) { tr[i] += u; } } intquery(int p){ int res = 0; for (int i = p; i > 0; i -= lowbit(i)) res += tr[i]; return res; } int a[1010100], d[1010100]; intmain(){ cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> a[i]; } for (int i = 1; i <= n; i++) { d[i] = a[i] - (i == 1 ? 0 : a[i - 1]); update(i, d[i]); } for (int i = 1; i <= m; i++) { cin >> op; if (op == 1) { cin >> x >> y >> k; update(x, k); update(y + 1, -k); } else { cin >> x; cout << query(x) << '\n'; } } return0; }
intlowbit(int x){ return x & -x; } voidupdate(int p, int u){ for (int i = p; i <= n; i += lowbit(i)) tr[i] += u; } intquery(int u){ int res = 0; for (int i = u; i > 0; i -= lowbit(i)) res += tr[i]; return res; }
intmain(){ cin >> n >> m; for (int i = 1; i <= n; i++) { scanf("%d", &l); update(i, l); } for (int i = 1; i <= m; i++) { scanf("%d%d", &l, &r); printf("%d\n", query(r) - query(l - 1)); } }
int tr[101010], a[101010], b[101010], n, k; int ls[101010], rs[101010]; //左面&右面每个X的结果 intlowbit(int x){ return x & -x; } voidupdate(int p, int u){ for (int i = p; i <= n; i += lowbit(i)) tr[i] += u; } intquery(int u){ int res = 0; for (int i = u; i > 0; i -= lowbit(i)) res += tr[i]; return res; } intmain(){ cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; b[i] = a[i]; } sort(b + 1, b + 1 + n); n = unique(b + 1, b + 1 + n) - b - 1; for (int i = 1; i <= n; i++) {
a[i] = lower_bound(b + 1, b + 1 + n, a[i]) - b; // cout << a[i] << " "; update(a[i], 1); ls[i] = query(n) - query(a[i]); //这里必须用query(n) } // cout << endl; memset(tr, 0, sizeof tr); for (int i = n; i >= 1; i--) { update(a[i], 1); rs[i] = query(n) - query(a[i]); //这里必须用query(n) } for (int i = 1; i <= n; i++) { // cout << ls[i] << " " << rs[i] << endl; if (ls[i] > rs[i]) { if (rs[i] * 2 < ls[i]) k++; } else { if (ls[i] * 2 < rs[i]) k++; } } cout << k << endl; }
intlb(int x){ return x & -x; } voidupdate(int p, int u){ for (int i = p; i <= n; i += lb(i)) tr[i] += u; } intquery(int u){ int res = 0; for (int i = u; i > 0; i -= lb(i)) res += tr[i]; return res; } intmain(){ cin >> n >> m; for (int i = 1; i <= m; i++) { int k, l; scanf("%d%d",&k,&l); if (k == 2) { printf("%d\n", query(l) % 2); } else { int r; scanf("%d",&r); update(l, 1); update(r + 1, -1); } } }
/* 阅读理解+水题一道 首先校长在m节车厢就是查询1-m的总人数 有人上下车就是update,下车就是update一个负数 几节车厢就是几个值来建树状数组 */ #include<bits/stdc++.h> usingnamespace std; int n, m, tr[10101000]; intlowbit(int x){ return x & -x; } voidupdate(int p, int u){ for (int i = p; i <= n; i += lowbit(i)) tr[i] += u; } intquery(int p){ int res = 0; for (int i = p; i > 0; i -= lowbit(i)) res += tr[i]; return res; } intmain(){ cin >> n >> m; for (int i = 1; i <= m; i++) { char op[2]; int l, r; scanf("%s%d", &op, &l);//可恶只能输入字符数组 if (op[0] == 'A') { printf("%d\n", query(l)); } elseif (op[0] == 'B') { scanf("%d", &r); update(l, r); } else { scanf("%d", &r); update(l, -r); } } }
/* 经典阅读理解。 首先,阅读理解就是一个冒泡排序的板子,什么意思呢?就是每次将一个字母从前往后移动直到它周围的数的大小关系合适。 我们先要明白一个事就是不能暴力。平方复杂度直接炸了 每当我们移动一个数到正确的位置,cnt就加一。 而对于每一个数a[i]而言,在a[i]前面而且比a[i]大的数一定要跑到a[i]后面才能有序。 每轮排序,每个数只会被他前面比他大的数交换一次,因此如果a[i]前面有X个比他大的数,那这二者就会交换X+1次(有一次用于验证数组是否有序) 那我们只需要统计有多少个数在他前面且比他大就行了,这部分的做法请看上一题的说明,最后选那个X最大的数+1作为答案。 */ #include<bits/stdc++.h> usingnamespace std; int n, tr[1010101], ans, a[1010101], b[1010101]; intlb(int x){ return x & -x; } voidupdate(int p, int u){ for (int i = p; i <= n; i += lb(i)) tr[i] += u; }
intquery(int u){ int rss = 0; for (int i = u; i > 0; i -= lb(i)) rss += tr[i]; return rss; }
intmain(){ cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; b[i] = a[i]; } sort(b + 1, b + 1 + n); int k = unique(b + 1, b + 1 + n) - b - 1; for (int i = 1; i <= n; i++) { a[i] = lower_bound(b + 1, b + 1 + k, a[i]) - b; ans = max(query(k) - query(a[i]), ans); update(a[i], 1); } cout << ans + 1 << endl; }
int tr[1050][1051], n, m, x, y, k; intlb(int x){ return x & -x; } voidupdate(int x, int y, int u){ for (int i = x; i <= n; i += lb(i)) { for (int j = y; j <= n; j += lb(j)) { tr[i][j] += u; } } } intquery(int x, int y){ int res = 0; for (int i = x; i > 0; i -= lb(i)) { for (int j = y; j > 0; j -= lb(j)) { res += tr[i][j]; } } return res; } intquery_lr(int x, int y, int u, int v){//特殊标注 returnquery(u, v) - query(x - 1, v) - query(u, y - 1) + query(x - 1, y - 1); }
intmain(){ cin >> n; for (int i = 1;; i++) { int u, v; scanf("%d", &k); if (k == 3) return0; scanf("%d%d%d", &x, &y, &u); if (k == 1) { update(x + 1, y + 1, u); } elseif (k == 2) { scanf("%d", &v); printf("%d\n", query_lr(x + 1, y + 1, u + 1, v + 1)); } elsereturn0; } }
int tr[101010], n, a[101010], c[101010]; intlowbit(int x){ return x & -x; } voidupdate(int p, int u){ for (int i = p; i <= n; i += lowbit(i)) tr[i] += u; } intquery(int u){ int res = 0; for (int i = u; i > 0; i -= lowbit(i)) res += tr[i]; return res; } intmain(){ cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; update(i, 1); } for (int i = n; i >= 1; i--) { int l = 1, r = n; while (l <= r) { int mid = l + r >> 1; if (query(mid)-1 >= a[i]) r = mid - 1; else l = mid + 1; } c[i] = l; update(l, -1); } for (int i = 1; i <= n; i++) cout << c[i] << "\n"; }