QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#611712#7030. Ultraman vs. Aodzilla and Bodzillaucup-team4906#TL 0ms0kbC++205.9kb2024-10-04 22:17:232024-10-04 22:17:24

Judging History

你现在查看的是最新测评结果

  • [2024-10-04 22:17:24]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2024-10-04 22:17:23]
  • 提交

answer

#include<bits/stdc++.h>
#define F(i, a, b) for(int i = a; i <= b; i ++)
#define pii pair<int, int> 
#define fi first
#define se second
#define int long long

using namespace std;
const int N = 3e5 + 10;
int n, m, is_q[N];
pii a[N];
pii res[N];
int ans[N], Y[N];
typedef array<int, 3> a3;
int f1[N], f2[N];

vector<a3> op1[N], op2[N];

int lowbit(int x) {return x & -x;}
void add1(int x, int d) {for(; x <= n; x += lowbit(x)) f1[x] += d;}
int cal1(int l, int r) {
    if(l > r) return 0;
    int res = 0; l --;
    for(; r; r -= lowbit(r)) res += f1[r];
    for(; l; l -= lowbit(l)) res -= f1[l];
    return res; 
}
void add2(int x, int d) {for(; x <= n; x += lowbit(x)) f2[x] += d;}
int cal2(int l, int r) {
    if(l > r) return 0;
    int res = 0; l --;
    for(; r; r -= lowbit(r)) res += f2[r];
    for(; l; l -= lowbit(l)) res -= f2[l];
    return res; 
}

void sol() {
    cin >> n >> m;
    F(i, 1, n) {
        int x, y; cin >> x >> y;
        a[i] = {x, y};
        Y[x] = y;
    }
    F(i, 1, m) ans[i] = 0, is_q[i] = 0;
    F(i, 1, n) op1[i].clear(), op2[i].clear(), f1[i] = f2[i] = 0;
    if(n == 1) {
        F(i, 1, m) {
            char op; cin >> op;
            if(op == '!') cout << "0\n";
            else if(op == '?') {
                int x; cin >> x;
                cout << 1 << " " << 1 << "\n";
            }
        }
        return;
    }
    int x1 = 1, y1 = 1, x2 = n, y2 = n, fx1 = 1, fx2 = n, fy1 = 1, fy2 = n;
    int f1 = 0, f2 = 0;
    // x1: 包含了哪些位置 fx1: 目前的实际位置 
    // f1 是否合并上下的 只保留fx1
    int tot1 = 0, tot2 = 0;
    F(i, 1, m) {
        char op; cin >> op;
        if(op == '!') {
            is_q[i] = 0;
            if(f1 && f2) ans[i] = n * (n - 1) / 2;
            else if(f1) {
                ans[i] = y1 + n - y2 + 1;
            } else if(f2) {
                ans[i] = x1 + n - x2 + 1;
            } else {
                // op1 表示小于等于这个x的限制
                op1[fx1].push_back({fy1, 0, i});
                op1[fx1].push_back({fy2, 1, i});
                op2[fx2].push_back({fy1, 0, i});
                op2[fx2].push_back({fy2, 1, i});
            }
        } else if(op == '?') {
            is_q[i] = 2;
            int p; cin >> p;
            auto [x, y] = a[p];
            if(f1) x = fx1;
            else if(x <= x1) x = fx1;
            else if(x >= x2) x = fx2;
            else x -= tot1;
            if(f2) x = fy1;
            else if(y <= y1) y = fy1;
            else if(y >= y2) y = fy2;
            else y -= tot2;
            res[i] = {x, y}; 
        } else {
            is_q[i] = 1;
            int x; cin >> x;
            if(op == 'U') {
                tot1 += x;
                if(f1) { // 当前已经合并了
                    fx1 = max(1ll, fx1 - x);
                    continue;
                }
                // 挪到1的位置
                int nd = min(fx1 - 1, x);
                x -= nd; 
                fx1 -= nd, fx2 -= nd;
                while(x) {
                    x1 ++, fx2 --;
                    if(x1 == x2) {
                        assert(fx2 == 1);
                        f1 = 1;
                        break;
                    }
                    x --;
                }
            } else if(op == 'D') {
                tot1 -= x;
                if(f1) {
                    fx1 = min(n, fx1 + x);
                    continue;
                }
                int nd = min(n - fx2, x);
                x -= nd; 
                fx1 += nd, fx2 += nd;
                while(x) {
                    x2 --, fx1 ++;
                    if(x1 == x2) {
                        assert(fx1 == n);
                        assert(fx1 == fx2);
                        f1 = 1;
                        break;
                    }
                    x --;
                }
            } else if(op == 'L') {
                tot2 += x;
                if(f2) {
                    fy1 = max(1ll, fy1 - x);
                    continue;
                }
                int nd = min(fy1 - 1, x);
                x -= nd; 
                fy1 -= nd, fy2 -= nd;
                while(x) {
                    y1 ++, fy2 --;
                    if(y1 == y2) {
                        assert(fy2 == 1);
                        f2 = 1;
                        break;
                    }
                    x --;
                }
            } else {    
                tot2 -= x;
                if(f2) {
                    fy1 = min(n, fy1 + x);
                    continue;
                }
                int nd = min(n - fy2, x);
                x -= nd; 
                fy1 += nd, fy2 += nd;
                while(x) {
                    y2 --, fy1 ++;
                    if(x1 == x2) {
                        assert(fy1 == n);
                        assert(fy1 == fy2);
                        f2 = 1;
                        break;
                    }
                    x --;
                }
            }
        }
    }
    F(x, 1, n) {
        add1(Y[x], 1);
        for(auto [y, flag, id] : op1[x]) {
            int sum = 0;
            if(flag == 0) sum = cal1(1, y);
            else sum = cal1(y, n);
            ans[id] += 1ll * sum * (sum - 1) / 2;
        }
    }
    for(int x = n; x >= 1; x --) {
        add2(Y[x], 1);
        for(auto [y, flag, id] : op2[x]) {
            int sum = 0;
            if(flag == 0) sum = cal2(1, y);
            else sum = cal2(y, n);
            ans[id] += 1ll * sum * (sum - 1) / 2;
        }
    }

    F(i, 1, m) {
        if(is_q[i] == 2) cout << res[i].fi << " " << res[i].se << "\n";
        if(is_q[i] == 0) cout << ans[i] << "\n";
    }
}
 
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t; cin >> t;
    F(i, 1, t) sol();
    return 0;
}

详细

Test #1:

score: 0
Time Limit Exceeded

input:

2
5 15 5 25
5 15 25 5

output:


result: