답안 #1106244

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1106244 2024-10-29T16:04:19 Z zNatsumi 가로등 (APIO19_street_lamps) C++17
100 / 100
1965 ms 125196 KB
#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> ii;
typedef tuple<int, int, int> Que;

const int N = 3e5 + 5,
          INF = 1e9;

int n, q;
ii range[N];
string s;
Que query[N];

struct BIT2D{
  vector<int> node[N], bit[N];

  void fake_upd(int x, int y){
    for(int i = x; i <= n; i += i & -i)
      node[i].push_back(y);
  }
  void fake_update(int x, int y, int u, int v){
    fake_upd(x, y);
    fake_upd(x, v + 1);
    fake_upd(u + 1, y);
    fake_upd(u + 1, v + 1);
  }
  void fake_get(int x, int y){
    for(int i = x; i > 0; i -= i & -i)
      node[i].push_back(y);
  }

  void build(){
    for(int i = 1; i <= n; i++) if(node[i].size()){
      sort(node[i].begin(), node[i].end());
      node[i].erase(unique(node[i].begin(), node[i].end()), node[i].end());
      bit[i].assign(node[i].size() + 1, 0);
    }
  }

  void upd(int x, int y, int val){
    for(int i = x; i <= n; i += i & -i)
      for(int j = lower_bound(node[i].begin(), node[i].end(), y) - node[i].begin() + 1; j <= node[i].size(); j += j & -j)
        bit[i][j - 1] += val;
  }

  void update(int x, int y, int u, int v, int val){
    upd(x, y, val);
    upd(x, v + 1, -val);
    upd(u + 1, y, -val);
    upd(u + 1, v + 1, val);
  }
  int get(int x, int y){
    int res = 0;
    for(int i = x; i > 0; i -= i & -i)
      for(int j = lower_bound(node[i].begin(), node[i].end(), y) - node[i].begin() + 1; j > 0; j -= j & -j)
        res += bit[i][j - 1];
    return res;
  }
} bit;

struct SegTree{
  int st[N << 2], lz[N << 2];

  void build(int tl, int tr, int i){
    lz[i] = -1;
    if(tl == tr){
      st[i] = (s[tl] == '1' ? 0 : INF);
      return;
    }
    int tm = tl + tr >> 1;
    build(tl, tm, i<<1);
    build(tm + 1, tr, i<<1|1);
    st[i] = max(st[i<<1], st[i<<1|1]);
  }
  void push(int i){
    if(lz[i] == -1) return;
    st[i<<1] = st[i<<1|1] = lz[i<<1] = lz[i<<1|1] = lz[i];
    lz[i] = -1;
  }

  void update(int l, int r, int val, int tl, int tr, int i){
    if(r < tl || tr < l || l > r) return;
    if(l <= tl && tr <= r){
      st[i] = val;
      lz[i] = val;
      return;
    }
    if(tl != tr) push(i);
    int tm = tl + tr >> 1;
    update(l, r, val, tl, tm, i<<1);
    update(l, r, val, tm + 1, tr, i<<1|1);
    st[i] = max(st[i<<1], st[i<<1|1]);
  }

  int get(int l, int r, int tl, int tr, int i){
    if(r < tl || tr < l || l > r) return 0;
    if(l <= tl && tr <= r) return st[i];
    if(tl != tr) push(i);
    int tm = tl + tr >> 1;
    return max(get(l, r, tl, tm, i<<1), get(l, r, tm + 1, tr, i<<1|1));
  }
} it;

struct BIT{
  int bit[N];
  void upd(int i, int x){
    for(; i <= n + 1; i += i & -i) bit[i] += x;
  }
  int get(int i){
    int res = 0;
    for(; i > 0; i -= i & -i) res += bit[i];
    return res;
  }
} b;

int findL(int i){
  int l = 1, r = i - 1, res = 0;
  while(l <= r){
    int mid = l + r >> 1;
    if(b.get(i - 1) - b.get(mid - 1) >= 1) l = (res = mid) + 1;
    else r = mid - 1;
  }
  return res + 1;
}

int findR(int i){
  int l = i + 1, r = n, res = n + 1;
  while(l <= r){
    int mid = l + r >> 1;
    if(b.get(mid) - b.get(i) >= 1) r = (res = mid) - 1;
    else l = mid + 1;
  }
  return res - 1;
}

void init(){
  for(int i = 1; i <= n; i++) if(s[i] == '0') b.upd(i, 1);
  string tmp = s;

  for(int t = 1; t <= q; t++){
    auto [ty, x, y] = query[t];

    if(ty == 0){
      if(s[x] == '0'){
        int l = findL(x),
            r = findR(x);
        range[t] = {l, r};

        s[x] = '1';
        b.upd(x, -1);

        if(l <= x - 1) bit.fake_update(l, l, x - 1, x - 1);
        if(x + 1 <= r) bit.fake_update(x + 1, x + 1, r, r);

      }else{
        int l = findL(x),
            r = findR(x);
        range[t] = {l, r};
        s[x] = '0';
        b.upd(x, 1);

        bit.fake_update(l, l, r, r);
      }
    }else{
      bit.fake_get(x, y);
    }
  }
  bit.build();
  s = tmp;
}

void solve(){
  it.build(1, n, 1);

  for(int t = 1; t <= q; t++){
    auto [ty, x, y] = query[t];

    if(ty == 0){
      if(s[x] == '0'){
        int l, r; tie(l, r) = range[t];
        s[x] = '1';

        if(l <= x - 1) bit.update(l, l, x - 1, x - 1, t - it.get(l, x - 1, 1, n, 1));
        if(x + 1 <= r) bit.update(x + 1, x + 1, r, r, t - it.get(x + 1, r, 1, n, 1));
        it.update(l, r, t, 1, n, 1);

      }else{
        int l, r; tie(l, r) = range[t];
        s[x] = '0';

        bit.update(l, l, r, r, t - it.get(l, r, 1, n, 1));
        it.update(l, r, t, 1, n, 1);
        it.update(x, x, INF, 1, n, 1);
      }
    }else{
      auto tmp = t - it.get(x, y, 1, n, 1);
      cout << bit.get(x, y) + (tmp >= 0 ? tmp : 0) << "\n";
    }
  }
}

int32_t main(){
  cin.tie(0)->sync_with_stdio(0);
//  #define task "test"
//  if(fopen(task ".inp", "r")){
//    freopen(task ".inp", "r", stdin);
//    freopen(task ".out", "w", stdout);
//  }
  cin >> n >> q >> s;
  s = " " + s;

  for(int i = 1; i <= q; i++){
    string ty; cin >> ty;
    if(ty == "toggle"){
      int x; cin >> x;
      query[i] = Que(0, x, -1);
    }else{
      int x, y; cin >> x >> y;
      query[i] = Que(1, x, y - 1);
    }
  }
  init();
  solve();
//  cerr << "TIME 1: " << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";

  return 0;
}

Compilation message

street_lamps.cpp: In member function 'void BIT2D::upd(int, int, int)':
street_lamps.cpp:44:91: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   44 |       for(int j = lower_bound(node[i].begin(), node[i].end(), y) - node[i].begin() + 1; j <= node[i].size(); j += j & -j)
      |                                                                                         ~~^~~~~~~~~~~~~~~~~
street_lamps.cpp: In member function 'void SegTree::build(int, int, int)':
street_lamps.cpp:72:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   72 |     int tm = tl + tr >> 1;
      |              ~~~^~~~
street_lamps.cpp: In member function 'void SegTree::update(int, int, int, int, int, int)':
street_lamps.cpp:91:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   91 |     int tm = tl + tr >> 1;
      |              ~~~^~~~
street_lamps.cpp: In member function 'int SegTree::get(int, int, int, int, int)':
street_lamps.cpp:101:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  101 |     int tm = tl + tr >> 1;
      |              ~~~^~~~
street_lamps.cpp: In function 'int findL(int)':
street_lamps.cpp:121:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  121 |     int mid = l + r >> 1;
      |               ~~^~~
street_lamps.cpp: In function 'int findR(int)':
street_lamps.cpp:131:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  131 |     int mid = l + r >> 1;
      |               ~~^~~
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 20816 KB Output is correct
2 Correct 3 ms 20816 KB Output is correct
3 Correct 4 ms 20996 KB Output is correct
4 Correct 4 ms 20868 KB Output is correct
5 Correct 4 ms 20816 KB Output is correct
6 Correct 3 ms 20816 KB Output is correct
7 Correct 4 ms 20948 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 250 ms 37984 KB Output is correct
2 Correct 351 ms 46108 KB Output is correct
3 Correct 637 ms 53796 KB Output is correct
4 Correct 1315 ms 94368 KB Output is correct
5 Correct 1573 ms 106240 KB Output is correct
6 Correct 1341 ms 100452 KB Output is correct
7 Correct 585 ms 67012 KB Output is correct
8 Correct 579 ms 68168 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 5 ms 21072 KB Output is correct
2 Correct 5 ms 21072 KB Output is correct
3 Correct 5 ms 21072 KB Output is correct
4 Correct 4 ms 21072 KB Output is correct
5 Correct 1900 ms 125196 KB Output is correct
6 Correct 1965 ms 119952 KB Output is correct
7 Correct 1557 ms 107588 KB Output is correct
8 Correct 636 ms 68784 KB Output is correct
9 Correct 93 ms 30268 KB Output is correct
10 Correct 100 ms 30908 KB Output is correct
11 Correct 107 ms 31156 KB Output is correct
12 Correct 625 ms 67844 KB Output is correct
13 Correct 629 ms 69044 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 21072 KB Output is correct
2 Correct 5 ms 21024 KB Output is correct
3 Correct 5 ms 21240 KB Output is correct
4 Correct 6 ms 21168 KB Output is correct
5 Correct 642 ms 62616 KB Output is correct
6 Correct 976 ms 80296 KB Output is correct
7 Correct 1347 ms 96428 KB Output is correct
8 Correct 1876 ms 114084 KB Output is correct
9 Correct 434 ms 53572 KB Output is correct
10 Correct 331 ms 50200 KB Output is correct
11 Correct 433 ms 54592 KB Output is correct
12 Correct 330 ms 51108 KB Output is correct
13 Correct 430 ms 53664 KB Output is correct
14 Correct 317 ms 50884 KB Output is correct
15 Correct 631 ms 66916 KB Output is correct
16 Correct 635 ms 69044 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 20816 KB Output is correct
2 Correct 3 ms 20816 KB Output is correct
3 Correct 4 ms 20996 KB Output is correct
4 Correct 4 ms 20868 KB Output is correct
5 Correct 4 ms 20816 KB Output is correct
6 Correct 3 ms 20816 KB Output is correct
7 Correct 4 ms 20948 KB Output is correct
8 Correct 250 ms 37984 KB Output is correct
9 Correct 351 ms 46108 KB Output is correct
10 Correct 637 ms 53796 KB Output is correct
11 Correct 1315 ms 94368 KB Output is correct
12 Correct 1573 ms 106240 KB Output is correct
13 Correct 1341 ms 100452 KB Output is correct
14 Correct 585 ms 67012 KB Output is correct
15 Correct 579 ms 68168 KB Output is correct
16 Correct 5 ms 21072 KB Output is correct
17 Correct 5 ms 21072 KB Output is correct
18 Correct 5 ms 21072 KB Output is correct
19 Correct 4 ms 21072 KB Output is correct
20 Correct 1900 ms 125196 KB Output is correct
21 Correct 1965 ms 119952 KB Output is correct
22 Correct 1557 ms 107588 KB Output is correct
23 Correct 636 ms 68784 KB Output is correct
24 Correct 93 ms 30268 KB Output is correct
25 Correct 100 ms 30908 KB Output is correct
26 Correct 107 ms 31156 KB Output is correct
27 Correct 625 ms 67844 KB Output is correct
28 Correct 629 ms 69044 KB Output is correct
29 Correct 4 ms 21072 KB Output is correct
30 Correct 5 ms 21024 KB Output is correct
31 Correct 5 ms 21240 KB Output is correct
32 Correct 6 ms 21168 KB Output is correct
33 Correct 642 ms 62616 KB Output is correct
34 Correct 976 ms 80296 KB Output is correct
35 Correct 1347 ms 96428 KB Output is correct
36 Correct 1876 ms 114084 KB Output is correct
37 Correct 434 ms 53572 KB Output is correct
38 Correct 331 ms 50200 KB Output is correct
39 Correct 433 ms 54592 KB Output is correct
40 Correct 330 ms 51108 KB Output is correct
41 Correct 430 ms 53664 KB Output is correct
42 Correct 317 ms 50884 KB Output is correct
43 Correct 631 ms 66916 KB Output is correct
44 Correct 635 ms 69044 KB Output is correct
45 Correct 81 ms 32040 KB Output is correct
46 Correct 178 ms 36420 KB Output is correct
47 Correct 662 ms 62336 KB Output is correct
48 Correct 1288 ms 98716 KB Output is correct
49 Correct 114 ms 31544 KB Output is correct
50 Correct 112 ms 31288 KB Output is correct
51 Correct 121 ms 31856 KB Output is correct
52 Correct 145 ms 33592 KB Output is correct
53 Correct 145 ms 33592 KB Output is correct
54 Correct 146 ms 33592 KB Output is correct