Showing posts with label BIT. Show all posts
Showing posts with label BIT. Show all posts

Saturday, February 6, 2021

Atcoder.arc068_c Snuke Line

1.Problem
https://atcoder.jp/contests/arc068/tasks/arc068_c

2.Idea
Using BIT like an imos method in order to update intervals.

3.Source

 class BIT { //1 -indexed  
      const int n;  
      vector<Int> bit;  
 public:  
      BIT(int _n = 0) : n(_n), bit(n + 1, 0) {}  
      void add(int i, const Int x = 1) { for (i++; i <= n; i += i&-i) bit[i] += x; }  
      Int sum(int i) { Int x = 0; for (i++; i; i -= i & -i) x += bit[i]; return x; }  
      Int sum(int i, int j) { return sum(j) - sum(i - 1); }  
 };  
 vector<pair<int, int>> range[N];  
 void solve()  
 {  
      int n, m;  
      cin >> n >> m;  
      REP(i, n) {  
           int l, r; cin >> l >> r; 
           // Holding the intervals by the length 
           range[r - l + 1].push_back(make_pair(l, r));  
      }  
      BIT bit(m + 1);  
      int up = n;  
      RREP(d, m) {  
           for (pair<int, int> p : range[d]) {  
                // Here is the imos in interval
                bit.add(p.first, 1);  
                bit.add(p.second + 1, -1);  
                up--;  
           }  
           int cnt = 0;  
           // This takes only log(d)
           for (int i = d; i <= m; i += d) {  
                cnt += bit.sum(i);  
           }  
           cout << cnt + up << endl;  
      }  
 }  

Thursday, February 4, 2021

Atcoder.abc127_f Absolute Minima

1.Problem
https://atcoder.jp/contests/abc127/submissions/5607909

2.Idea
Using BIT to find and calc the median value.
Credit

3.Source

 const int N = 200005;  
 //////////////////////////////  
 template<typename T>  
 struct BIT {  
      int n;  
      vector<T> dat;  
      BIT(int n = 0) {  
           initialize(n);  
      }  
      void initialize(int nin) {  
           n = nin;  
           dat.resize(n);  
           for (int i = 0; i<n; i++) dat[i] = 0;  
      }  
      T sum(int i) {  
           T s = 0;  
           while (i >= 0) {  
                s += dat[i];  
                i = (i & (i + 1)) - 1;  
           }  
           return s;  
      }  
      T sum_between(int i, int j) {  
           if (i > j) return 0;  
           return sum(j) - sum(i - 1);  
      }  
      void plus(int i, T x) {  
           while (i < n) {  
                dat[i] += x;  
                i |= i + 1;  
           }  
      }  
      // a[0]+...+a[ret] >= x  
      int lower_bound(T x) {  
           int ret = -1;  
           int k = 1;  
           while (2 * k <= n) k <<= 1;  
           for (; k>0; k >>= 1) {  
                if (ret + k < n && dat[ret + k] < x) {  
                     x -= dat[ret + k];  
                     ret += k;  
                }  
           }  
           return ret + 1;  
      }  
 };  
 Int T[N], A[N], B[N];  
 void solve()  
 {  
      int q;  
      cin >> q;  
      vector<int> as;  
      REP(i, q) {  
           cin >> T[i];  
           if (T[i] == 1) {  
                cin >> A[i] >> B[i];  
                as.push_back(A[i]);  
           }  
      }  
      sort(as.begin(), as.end());  
      as.erase(unique(as.begin(), as.end()), as.end());  
      map<int, int> mp;  
      int sz = as.size();  
      REP(i, sz) mp[as[i]] = i;  
      BIT<Int> bitnum(sz);  
      BIT<Int> bitsum(sz);  
      Int fix = 0;  
      int all = 0;  
      REP(i, q) {  
           if (T[i] == 1) {  
                int a = mp[A[i]];  
                bitsum.plus(a, A[i]);  
                bitnum.plus(a, 1);  
                fix += B[i];  
                all++;  
           }  
           else {  
                Int ans = fix;  
                int idx = bitnum.lower_bound((all + 1) / 2);  
                ans += bitsum.sum_between(idx + 1, sz - 1);  
                ans -= as[idx] * bitnum.sum_between(idx + 1, sz - 1);  
                ans -= bitsum.sum_between(0, idx - 1);  
                ans += as[idx] * bitnum.sum_between(0, idx - 1);  
                cout << as[idx] << " " << ans << endl;  
           }  
      }  
 }   

Sunday, January 24, 2021

Atcoder.chokudai_S001_h LIS

1.Problem
https://atcoder.jp/contests/chokudai_S001/tasks/chokudai_S001_h

2.Idea
Using BIT Max Range Query

3.Source

 const int N = 100005;  
 //////////////////////////////  
 class BIT {  //1 -indexed
      const int n;  
      vector<Int> bit;  
 public:  
      BIT(int _n = 0) : n(_n), bit(n + 1, 0) {}  
      void add(int i, const Int x = 1) { for (i++; i <= n; i += i&-i) bit[i] += x; }  
      Int sum(int i) { Int x = 0; for (i++; i; i -= i & -i) x += bit[i]; return x; }  
      Int sum(int i, int j) { return sum(j) - sum(i - 1); }  
 };  
 struct FenwickTreeMin {  
      vector<int> bit;  //0 -indexed
      int n;  
      const int INF = (int)1e9;  
      FenwickTreeMin(int n) {  
           this->n = n;  
           bit.assign(n, INF);  
      }  
      FenwickTreeMin(vector<int> a) : FenwickTreeMin(a.size()) {  
           for (size_t i = 0; i < a.size(); i++)  
                update(i, a[i]);  
      }  
      int getmin(int r) {  
           int ret = INF;  
           for (; r >= 0; r = (r & (r + 1)) - 1)  
                ret = min(ret, bit[r]);  
           return ret;  
      }  
      void update(int idx, int val) {  
           for (; idx < n; idx = idx | (idx + 1))  
                bit[idx] = min(bit[idx], val);  
      }  
 };  
 struct FenwickTreeMax {  
      vector<int> bit;  // 0 - indexed
      int n;  
      FenwickTreeMax(int n) {  
           this->n = n;  
           bit.assign(n, -INF);  
      }  
      FenwickTreeMax(vector<int> a) : FenwickTreeMax(a.size()) {  
           for (size_t i = 0; i < a.size(); i++)  
                update(i, a[i]);  
      }  
      int getMax(int r) {  
           int ret = -INF;  
           for (; r >= 0; r = (r & (r + 1)) - 1)  
                ret = max(ret, bit[r]);  
           return ret;  
      }  
      void update(int idx, int val) {  
           for (; idx < n; idx = idx | (idx + 1))  
                bit[idx] = max(bit[idx], val);  
      }  
 };  
 int n;  
 int a[N];  
 void solve()  
 {  
      cin >> n;  
      REP(i, n) cin >> a[i];  
      map<int, int> mp;  
      REP(i, n) mp[a[i]] = 0;  
      int i = 0;  
      for (auto it = mp.begin(); it != mp.end(); it++) {  
           it->second = i;  
           i++;  
      }  
      FenwickTreeMax ftm(n);  
      REP(i, n) {  
           int cur = mp[a[i]];  
           int tmp = ftm.getMax(cur - 1);  
           if(tmp == -INF) ftm.update(cur, 1);  
           else ftm.update(cur, tmp + 1);  
      }  
      cout << ftm.getMax(n - 1) << endl;  
 }  

Monday, May 18, 2020

POJ.3321 Apple Tree

1.Problme
http://poj.org/problem?id=3321

2.Idea
A good editorail using BIT.

3.Source
 const int MAX_N = 100009;  
 int table[MAX_N+1];  
 int BIT[MAX_N+1];  
 int tos[MAX_N+1];  
 int idx[MAX_N+1];  
 bool noApple[MAX_N+1];  
 vector<int> G[MAX_N+1];  
 int N, counter;  
 inline int readint(){  
   int ret = 0, x;  
   while(x=getchar(), !('0'<=x&&x<='9'));  
   ret = (x&15);  
   while(x=getchar(), '0'<=x&&x<='9') ret = (ret<<3) + (ret<<1) + (x&15);  
   return ret;  
 }  
 inline int sum(int n){int _R=0;for(;n;n-=n&-n)_R+=BIT[n];return _R;}  
 inline int sum(int from, int to){return sum(to-1)-sum(from-1);}  
 inline void add(int n, int x){for(;n<=N;n+=n&-n)BIT[n]+=x;}  
 inline void dfs(int v){  
      int gv = G[v].size();  
      table[v] = counter++;  
      for(int i=0; i<gv; i++){  
           if(!table[G[v][i]]) dfs(G[v][i]);  
      }  
      tos[table[v]] = counter;  
 }  
 int main(){  
      N = readint();  
      for(int i=0, x, y; i<N-1; i++){  
           x = readint(), y = readint();  
           G[x].push_back(y); G[y].push_back(x);  
      }  
      counter = 1;  
      dfs(1);  
      int M = readint();  
      for(int i=0, x; i<M; i++){  
           char op;  
           scanf(" %c ",&op);  
           x = table[readint()];  
           if(op=='Q'){  
                printf("%d\n", tos[x]-x-sum(x,tos[x]));  
           }  
           else{  
                noApple[x] = !noApple[x];  
                add(x,noApple[x]?1:-1);  
           }  
      }  
      return 0;  
 }