codechef Many Lists(树状数组 set)
程序员文章站
2022-12-23 13:07:20
题意 "题目链接" Sol 直接做肯定不好搞(反正我不会。。) 直接开$n$个Pair类型的set,维护每个数的出现位置 每次在set中二分后暴力合并即可 然后就是树状数组的基本操作了 时间复杂度:$O(nlog^2n)$ cpp include define Pair pair define MP ......
题意
sol
直接做肯定不好搞(反正我不会。。)
直接开\(n\)个pair类型的set,维护每个数的出现位置
每次在set中二分后暴力合并即可
然后就是树状数组的基本操作了
时间复杂度:\(o(nlog^2n)\)
#include<bits/stdc++.h> #define pair pair<int, int> #define mp make_pair #define fi first #define se second #define lb(x) (x & (-x)) using namespace std; const int maxn = 1e5 + 10, inf = 2147483647; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int n, m, t[maxn]; void add(int x, int v) { while(x <= n) t[x] += v, x += lb(x); } void addint(int l, int r, int val) { add(l, val); add(r + 1, -val); } int query(int x) { int ans = 0; while(x) ans += t[x], x -= lb(x); return ans; } set<pair> s[maxn]; #define sit set<pair>::iterator void add(int l, int r, int x) { set<pair> &s = s[x]; //printf("%d\n", s.size()); sit it = s.lower_bound(mp(l, r)); if(it != s.begin()) it--; // printf("%d %d\n", it -> fi, it -> se); while((it -> se >= l && it -> se <= r) || (it -> fi >= l && it -> se <= r)) { printf("%d %d\n", it -> fi, it -> se); l = min(l, it -> fi); r = max(r, it -> se); addint(it -> fi, it -> se, -1); s.erase(it); } s.insert(mp(l, r)); addint(l, r, 1); } int main() { n = read(); m = read(); for(int i = 1; i <= n; i++) s[i].insert(mp(inf, inf)); while(m--) { int opt = read(); if(opt == 0) {int l = read(), r = read(), val = read(); add(l, r, val);} else printf("%d\n", query(read())); } return 0; } /* 5 5 0 2 4 4 0 3 5 5 0 1 5 5 1 5 1 3 */
上一篇: js操作css样式,null和undefined的区别?
下一篇: 超简单钉钉打卡破解教程