답안 #63615

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
63615 2018-08-02T09:11:47 Z Just_Solve_The_Problem Min-max tree (BOI18_minmaxtree) C++11
29 / 100
735 ms 60272 KB
#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define ok puts("ok");
#define pii pair < int, int >
#define fr first
#define sc second
#define mk make_pair

const int N = (int)2e5 + 7;
const int inf = (int)1e9 + 7;

struct T {
  pii mn, mx;
  pii addmx, addmn;
  T() {
    mn = mk(-1, 0);
    mx = mk(inf, 0);
    addmn = mk(-1, 0);
    addmx = mk(inf, 0);
  }
};
T tree[N * 4];

struct query {
  int tp, a, b, val;
  query() {}
  query(int _tp, int _a, int _b, int _val) {
    tp = _tp;
    a = _a;
    b = _b;
    val = _val;
  }
};
query asq[N];

void push(int v, int l, int r) {
  if (tree[v].addmn.fr != -1) {
    if (l != r) {
      tree[v + v].addmn = max(tree[v + v].addmn, tree[v].addmn);
      tree[v + v + 1].addmn = max(tree[v + v + 1].addmn, tree[v].addmn);
    }
    tree[v].mn = max(tree[v].mn, tree[v].addmn);
    tree[v].addmn.fr = -1;
  }
  if (tree[v].addmx.fr != inf) {
    if (l != r) {
      tree[v + v].addmx = min(tree[v + v].addmx, tree[v].addmx);
      tree[v + v + 1].addmx = min(tree[v + v + 1].addmx, tree[v].addmx);
    }
    tree[v].mx = min(tree[v].mx, tree[v].addmx);
    tree[v].addmx.fr = inf;
  }
}

int n;
int asd;

// tp = 1, min
// tp = 2, MAX

void upd(int tp, int l, int r, int val, int v = 1, int tl = 1, int tr = n) {
  push(v, tl, tr);
  if (tl > r || tr < l) return ;
  if (l <= tl && tr <= r) {
    if (tp == 1) {
      tree[v].addmn = max(tree[v].addmn, mk(val, asd));
    } else if (tp == 2) {
      tree[v].addmx = min(tree[v].addmx, mk(val, asd));
    }
    push(v, tl, tr);
    return ;
  }
  int mid = (tl + tr) >> 1;
  upd(tp, l, r, val, v + v, tl, mid);
  upd(tp, l, r, val, v + v + 1, mid + 1, tr);
}

pii ar1[N], ar2[N];
int poss[N];

void buildget(int v = 1, int l = 1, int r = n) {
  push(v, l, r);
  if (l == r) {
    ar1[poss[l]] = tree[v].mx;
    ar2[poss[l]] = tree[v].mn;
    return ;
  }
  int mid = (l + r) >> 1;
  buildget(v + v, l, mid);
  buildget(v + v + 1, mid + 1, r);
}

vector < int > gr[N], gr1[N + N];
int pr[N];
int sz[N];
int chainpos[N], chain[N], chainsz[N], head[N];
int chsz = 1;
int lca[18][N];
int tin[N], tout[N];
int tiktak = 0, cur = 1;
int mt[N];
int used[N];
int prr[N + N];

void getsz(int v) {
  sz[v] = 1;
  tin[v] = ++tiktak;
  lca[0][v] = pr[v];
  for (int i = 1; i <= 17; i++) {
    lca[i][v] = lca[i - 1][lca[i - 1][v]];
  }
  for (int to : gr[v]) {
    if (to == pr[v]) continue;
    pr[to] = v;
    getsz(to);
    sz[v] += sz[to];
  }
  tout[v] = tiktak;
}

void build(int v, int ch) {
  poss[cur] = v;
  chainpos[v] = cur++;
  chainsz[ch]++;
  chain[v] = ch;
  if (chainsz[ch] == 1) {
    head[ch] = v;
  }
  int big = 0;
  for (int to : gr[v]) {
    if (to == pr[v]) continue;
    if (sz[to] > sz[big]) {
      big = to;
    }
  }
  if (big)
    build(big, ch);
  for (int to : gr[v]) {
    if (to == pr[v] || to == big) continue;
    build(to, ++chsz);
  }
}

bool upper(int a, int b) {
  return tin[a] <= tin[b] && tout[a] >= tout[b];
}

int getlca(int a, int b) {
  if (upper(a, b)) return a;
  if (upper(b, a)) return b;
  for (int i = 17; i >= 0; i--) {
    if (!upper(lca[i][a], b)) a = lca[i][a];
  }
  return lca[0][a];
}

void updm(int tp, int a, int b, int val) {
  int lc = getlca(a, b);
  while (chain[a] != chain[lc]) {
    upd(tp, chainpos[head[chain[a]]], chainpos[a], val);
    a = pr[head[chain[a]]];
  }
  while (chain[b] != chain[lc]) {
    upd(tp, chainpos[head[chain[b]]], chainpos[b], val);
    b = pr[head[chain[b]]];
  }
  if (chainpos[lc] + 1 <= max(chainpos[b], chainpos[a])) {
    upd(tp, chainpos[lc] + 1, max(chainpos[a], chainpos[b]), val);
  }
}

bool kuhn(int v) {
  if (used[v]) return 0;
  used[v] = 1;
  for (int to : gr1[v]) {
    if (mt[to] == -1 || kuhn(mt[to])) {
      mt[to] = v;
      prr[v] = to;
      return 1;
    }
  }
  return 0;
}

main() {
  memset(mt, -1, sizeof mt);
  memset(prr, -1, sizeof prr);
  scanf("%d", &n);
  for (int i = 1; i < n; i++) {
    int v, u;
    scanf("%d %d", &v, &u);
    gr[v].pb(u);
    gr[u].pb(v);
  }
  pr[1] = 1;
  getsz(1);
  build(1, 1);
  int q;
  scanf("%d", &q);
  for (int i = 1; i <= q; i++) {
    asd = i;
    char c;
    scanf("\n");
    int a, b, x;
    scanf("%c %d %d %d", &c, &a, &b, &x);
    if (c == 'M') {
      asq[i] = query(2, a, b, x);
      updm(2, a, b, x);
    } else {
      asq[i] = query(1, a, b, x);
      updm(1, a, b, x);
    }
  }

  buildget();
  for (int i = 2; i <= n; i++) {
//    cout << ar1[i].sc << ' ' << ar2[i].sc << endl;
    if (ar1[i].sc > 0 && ar1[i].sc <= q) {
      gr1[n + ar1[i].sc].pb(i);
//      cout << i << ' ' << ar1[i].sc << endl;
    }
    if (ar2[i].sc > 0 && ar2[i].sc <= q) {
      gr1[n + ar2[i].sc].pb(i);
//      cout << i << ' ' << ar2[i].sc << endl;
    }
  }
  int run = 1;
  while(run) {
    run = 0;
    for (int i = n + 1; i <= n + q; i++) {
      if (prr[i] == -1 && kuhn(i)) {
        run = 1;
      }
    }
    memset(used, 0, sizeof used);
  }
//  for (int i = 2; i <= n; i++) {
//    cout << i << ' ' << mt[i] - n << endl;
//  }
//  for (int i = 2; i <= n; i++) {
//    assert(prr[i] - n >= 1 && prr[i] - n <= q);
//  }
  for (int i = 2; i <= n; i++) {
    int val;
    if (mt[i] == -1) {
      val = 1;
    } else {
      val = asq[mt[i] - n].val;
    }
    printf("%d %d %d\n", i, pr[i], val);
  }
}
/*
5
1 2
1 3
3 4
3 5
4
m 2 4 1
M 4 5 2
M 2 3 5
m 2 3 4
*/

Compilation message

minmaxtree.cpp:188:6: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
 main() {
      ^
minmaxtree.cpp: In function 'int main()':
minmaxtree.cpp:191:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d", &n);
   ~~~~~^~~~~~~~~~
minmaxtree.cpp:194:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d %d", &v, &u);
     ~~~~~^~~~~~~~~~~~~~~~~
minmaxtree.cpp:202:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d", &q);
   ~~~~~^~~~~~~~~~
minmaxtree.cpp:206:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("\n");
     ~~~~~^~~~~~
minmaxtree.cpp:208:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%c %d %d %d", &c, &a, &b, &x);
     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 45 ms 42744 KB Output is correct
2 Correct 44 ms 42852 KB Output is correct
3 Correct 47 ms 42884 KB Output is correct
4 Correct 47 ms 42964 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 493 ms 59764 KB Output is correct
2 Correct 675 ms 59764 KB Output is correct
3 Correct 552 ms 59764 KB Output is correct
4 Correct 465 ms 60272 KB Output is correct
5 Correct 735 ms 60272 KB Output is correct
6 Correct 467 ms 60272 KB Output is correct
7 Correct 375 ms 60272 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 373 ms 60272 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 45 ms 42744 KB Output is correct
2 Correct 44 ms 42852 KB Output is correct
3 Correct 47 ms 42884 KB Output is correct
4 Correct 47 ms 42964 KB Output is correct
5 Correct 493 ms 59764 KB Output is correct
6 Correct 675 ms 59764 KB Output is correct
7 Correct 552 ms 59764 KB Output is correct
8 Correct 465 ms 60272 KB Output is correct
9 Correct 735 ms 60272 KB Output is correct
10 Correct 467 ms 60272 KB Output is correct
11 Correct 375 ms 60272 KB Output is correct
12 Incorrect 373 ms 60272 KB Output isn't correct
13 Halted 0 ms 0 KB -