답안 #826808

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
826808 2023-08-16T04:33:23 Z boyliguanhan Sails (IOI07_sails) C++17
100 / 100
226 ms 7804 KB
#include<bits/stdc++.h>
#define maintain(n) (sz[n] = sz[ch[n][0]]+sz[ch[n][1]] + 1)
using namespace std;
random_device rd1,rd2,rd3;
#define int long long
mt19937 rng(abs(rd1()+rd2()+rd3()+rd1()+rd2()+rd3()-chrono::steady_clock().now().time_since_epoch().count()));
#define N 100100
int ch[N][2], val[N], key[N], sz[N], root, cnt, lz[N];
void pd(int n) {
    if(lz[n]) {
        val[n]+=lz[n];
        if(ch[n][0])
            lz[ch[n][0]]+=lz[n];
        if(ch[n][1])
            lz[ch[n][1]]+=lz[n];
        lz[n]=0;
    }
}
void split(int n, int x, int &a, int &b) {
    if(!n) a = b = 0;
    else { pd(n);if(val[n] <= x) a = n,
        split(ch[n][1], x, ch[n][1], b);
    else b = n, split(ch[n][0], x, a, ch[b][0]);
    maintain(n);}
}
void split2(int n, int size, int&a, int &b){
    if(!n) a = b = 0;
    else { pd(n);if(sz[ch[n][0]] < size) a = n,
        split2(ch[n][1], size - sz[ch[n][0]]-1, ch[n][1], b);
    else
        b = n, split2(ch[n][0], size, a, ch[n][0]);
    maintain(n);}
}
int merge(int a, int b) {
    pd(a),pd(b);
    if(!a||!b) return a|b;
    if(key[a]<key[b]){ ch[a][1] = merge(ch[a][1], b);
        maintain(a); return a;}
    ch[b][0] = merge(a, ch[b][0]);
    maintain(b); return b;
}
void ins() {
    sz[++cnt] = 1;
    key[cnt] = rng();
    root = merge(cnt, root);
}
int getv(int rank) {
    int cur = root;
    while(cur) {
        pd(cur);
        if(rank==sz[ch[cur][0]]+1) break;
        if(rank <= sz[ch[cur][0]]) cur = ch[cur][0];
        else rank-=sz[ch[cur][0]]+1, cur = ch[cur][1];
    }
    return val[cur];
}   
int pre(int n) {
    pd(n);
    if(!n) return 0;
    return val[n]*(val[n]-1)/2+pre(ch[n][0])+pre(ch[n][1]);
}
int last, ans, temp;
signed main() {
    vector<pair<int, int>> v;
    int n;
    cin >> n;
    while(n--) {
        int a, b;
        cin >> a >> b;
        v.push_back({a,b});
    }
    sort(v.begin(), v.end());
    for(auto i: v) {
        while(sz[root]<i.first)
            ins();
        int cutval = getv(i.second);
        int x=0, y=0, z=0;
        split(root, cutval-1, x, y);
        split(y, cutval, y, z);
        int y2=0;
        split2(y, i.second-sz[x],y,y2);
        if(y)
            lz[y]++;
        if(x)
            lz[x]++;
        root = merge(merge(x,y2),merge(y,z));
    }
    cout << pre(root) << '\n';
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 588 KB Output is correct
2 Correct 15 ms 4928 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 17 ms 1988 KB Output is correct
2 Correct 39 ms 1356 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 35 ms 2632 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 101 ms 4032 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 194 ms 7084 KB Output is correct
2 Correct 171 ms 7148 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 170 ms 7492 KB Output is correct
2 Correct 103 ms 6736 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 226 ms 7804 KB Output is correct
2 Correct 150 ms 4536 KB Output is correct