답안 #1106220

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1106220 2024-10-29T14:38:51 Z zNatsumi 가로등 (APIO19_street_lamps) C++17
20 / 100
4396 ms 524288 KB
#include <bits/stdc++.h>

using namespace std;

typedef tuple<int, int, int> Que;

const int N = 1e6 + 10,
          INF = 1e9;

int n, q;
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)
      for(int j = y; j <= n; j += j & -j)
        node[i].push_back(j);
  }
  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)
      for(int j = y; j > 0; j -= j & -j)
        node[i].push_back(j);
  }

  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;

void init(){
  set<int> pos0;
  for(int i = 1; i <= n; i++) if(s[i] == '0') pos0.insert(i);
  pos0.insert(0); pos0.insert(n + 1);

  string tmp = s;

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

    if(ty == 0){
      if(s[x] == '0'){
        auto i = pos0.find(x);
        int l = *prev(i) + 1, r = *next(i) - 1;

        s[x] = '1';

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

        pos0.erase(x);
      }else{
        s[x] = '0';
        pos0.insert(x);

        auto i = pos0.find(x);
        int l = *prev(i) + 1, r = *next(i) - 1;

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

void solve(){
  set<int> pos0;
  for(int i = 1; i <= n; i++) if(s[i] == '0') pos0.insert(i);
  pos0.insert(0); pos0.insert(n + 1);

  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'){
        auto i = pos0.find(x);
        int l = *prev(i) + 1, r = *next(i) - 1;

        s[x] = '1';

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

        pos0.erase(x);
      }else{
        s[x] = '0';
        pos0.insert(x);

        auto i = pos0.find(x);
        int l = *prev(i) + 1, r = *next(i) - 1;

        bit.update(l, l, r, r, t - it.get(l, r, 1, n, 1));
        it.update(l, r, t, 1, n, 1);
        it.update(*i, *i, 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();

  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 'int32_t main()':
street_lamps.cpp:188:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  188 |     freopen(task ".inp", "r", stdin);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
street_lamps.cpp:189:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  189 |     freopen(task ".out", "w", stdout);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 51536 KB Output is correct
2 Correct 9 ms 51552 KB Output is correct
3 Correct 8 ms 51536 KB Output is correct
4 Correct 11 ms 51792 KB Output is correct
5 Correct 8 ms 51792 KB Output is correct
6 Correct 9 ms 51704 KB Output is correct
7 Correct 9 ms 51536 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 492 ms 109580 KB Output is correct
2 Correct 774 ms 135944 KB Output is correct
3 Correct 1556 ms 232728 KB Output is correct
4 Correct 4002 ms 455156 KB Output is correct
5 Runtime error 918 ms 524288 KB Execution killed with signal 9
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 52304 KB Output is correct
2 Correct 14 ms 52304 KB Output is correct
3 Correct 13 ms 52304 KB Output is correct
4 Correct 13 ms 51808 KB Output is correct
5 Runtime error 998 ms 524288 KB Execution killed with signal 9
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 10 ms 51792 KB Output is correct
2 Correct 11 ms 52048 KB Output is correct
3 Correct 12 ms 52304 KB Output is correct
4 Correct 14 ms 52460 KB Output is correct
5 Correct 1785 ms 253128 KB Output is correct
6 Correct 3099 ms 389204 KB Output is correct
7 Correct 4396 ms 517028 KB Output is correct
8 Runtime error 916 ms 524288 KB Execution killed with signal 9
9 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 51536 KB Output is correct
2 Correct 9 ms 51552 KB Output is correct
3 Correct 8 ms 51536 KB Output is correct
4 Correct 11 ms 51792 KB Output is correct
5 Correct 8 ms 51792 KB Output is correct
6 Correct 9 ms 51704 KB Output is correct
7 Correct 9 ms 51536 KB Output is correct
8 Correct 492 ms 109580 KB Output is correct
9 Correct 774 ms 135944 KB Output is correct
10 Correct 1556 ms 232728 KB Output is correct
11 Correct 4002 ms 455156 KB Output is correct
12 Runtime error 918 ms 524288 KB Execution killed with signal 9
13 Halted 0 ms 0 KB -