列表

详情


NC202232. OJ用户管理系统

描述

    某个不愿意透露姓名的OJ的用户编号为号用户在OJ中的(的一个排列)。
    OJ用如下二叉树结构管理用户:每个节点代表一个用户,二叉树按用户编号形成大根堆;按照用户的形成二叉搜索树。
    现在依次进行次操作,每次给定,要求交换号用户和号用户的,依次输出每次操作后各用户在二叉树上的深度变化量之和。 
    例如,分别为2 5 1 4 6 3,交换5号和6号的,交换前后的二叉树如下 :

输入描述

第一行输入表示数据组数
每组数据第一行输入两个整数.
第二行输入个整数 表示,保证是1到的排列.
接下来行每行输入一个整数.

输出描述

每组数据第行输出一个整数,表示第次操作的答案.

示例1

输入:

1
6 1
2 5 1 4 6 3
5

输出:

2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 202ms, 内存消耗: 5264K, 提交时间: 2020-02-22 13:29:57

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> point;
#define fi first
#define se second
const int N = 1e5 + 10;
int r[N], s[N];
int ch[N][2], fa[N], sz[N], dep[N];
int bit[N], n, q;
void add(int x, int v){for(;x<=n;x+=x&-x)bit[x]+=v;}
void add(int l, int r, int v){add(l,v),add(r+1,-v);}
int query(int x){int ret=0;for(;x>0;x-=x&-x)ret+=bit[x];return ret;}
void init() {
    for(int i = 1; i <= n; i++) {
        bit[i] = fa[i] = dep[i] = 0;
        ch[i][0] = ch[i][1] = 0;
        sz[i] = 1;
    }
}
void up(int x) {
    sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + 1;
}
void setfa(int x, int y, bool _r) {
    if(y) ch[y][_r] = x;
    if(x) fa[x] = y;
}
void build() {
    vector<int> stk;
    int nowroot = 0;
    for(int i = 1; i <= n; i++) {
        while(!stk.empty() && s[stk.back()] < s[i]) stk.pop_back();
        if(!stk.empty()) {
            setfa(ch[stk.back()][1], i, 0);
            setfa(i, stk.back(), 1);
        } else {
            setfa(nowroot, i, 0);
            nowroot = i;
        }
        stk.push_back(i);
    }
    for(int i = 1; i <= n; i++) up(r[i]);
    for(int i = n; i > 0; i--) dep[r[i]] = dep[fa[r[i]]] + 1;
    for(int i = 1; i <= n; i++) add(i, dep[i] - dep[i - 1]);
}
int rot(int &x, int &y) {
    int ret = 0;
    if(fa[x] != y) {
        ret = 2 * abs(query(x) - query(y));
    } else {
        int k = ch[y][1] == x;
        ret = sz[ch[x][k]] + sz[ch[y][k^1]];
        add(y - k*sz[ch[y][k^1]], y + (k^1)*sz[ch[y][k^1]], 1);
        add(x - (k^1)*sz[ch[x][k]], x + k*sz[ch[x][k]], -1);
        setfa(ch[x][k^1], y, k);
        setfa(x, fa[y], ch[fa[y]][1] == y);
        setfa(y, x, k^1);
        up(y);
        up(x);
    }
    swap(x, y);
    return ret;
}

int main() {
#ifdef local
    freopen("in.txt", "r", stdin);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int _; cin >> _;
    while(_--) {
        cin >> n >> q;
        for(int i = 1; i <= n; i++) cin >> r[i], s[r[i]] = i;
        init();
        build();
        while(q--) {
            int x; cin >> x;
            cout << rot(r[x], r[x + 1]) << '\n';
        }
    }
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 273ms, 内存消耗: 8796K, 提交时间: 2020-04-28 16:44:39

#include<bits/stdc++.h>
using namespace std;

int read(){int a; scanf("%d" , &a); return a;}
const int _ = 1e5 + 7;
int fa[_] , ch[_][2] , ql[_] , qr[_] , val[_] , pos[_] , dep[_] , N , Q , T , stk[_] , top;

#define lowbit(x) x & -x
int arr[_]; void add(int x , int v){while(x <= N){arr[x] += v; x += lowbit(x);}}
int qry(int x){int sum = 0; while(x){sum += arr[x]; x -= lowbit(x);} return sum;}

void upd(int x){ql[x] = ch[x][0] ? ql[ch[x][0]] : x; qr[x] = ch[x][1] ? qr[ch[x][1]] : x;}
void dfs(int x){if(x){dep[ch[x][0]] = dep[ch[x][1]] = dep[x] + 1; dfs(ch[x][0]); dfs(ch[x][1]); upd(x);}}
int rot(int x){
	add(ql[x] , -1); add(qr[x] + 1 , 1);
	bool f = ch[fa[x]][1] == x; int ans = qr[ch[x][f]] - ql[ch[x][f]] + 1 , y = fa[x] , z = fa[y] , w = ch[x][f ^ 1];
	fa[x] = z; ch[z][ch[z][1] == y] = x; fa[y] = x; ch[x][f ^ 1] = y; fa[w] = y; ch[y][f] = w;
	upd(y); upd(x); add(ql[y] , 1); add(qr[y] + 1 , -1); return ans + qr[ch[y][f ^ 1]] - ql[ch[y][f ^ 1]] + 1;
}

int main(){
	qr[0] = -1; val[0] = 1e9;
	for(T = read() ; T ; --T){
		N = read(); Q = read(); for(int i = 1 ; i <= N ; ++i){pos[i] = read(); val[pos[i]] = i;}
		top = 0; memset(ch , 0 , sizeof(ch)); memset(arr , 0 , sizeof(arr));
		for(int i = 1 ; i <= N ; ++i){
			int pre = 0; while(val[stk[top]] < val[i]) pre = stk[top--];
			fa[ch[stk[top]][1] = i] = stk[top]; fa[ch[i][0] = pre] = i; stk[++top] = i;
		}
		dfs(stk[1]); for(int i = 1 ; i <= N ; ++i) add(i , dep[i] - dep[i - 1]);
		while(Q--){
			int p = read() , &x = pos[p] , &y = pos[p + 1];
			printf("%d\n" , fa[x] == y ? rot(x) : 2 * abs(qry(x) - qry(y)));
			swap(x , y);
		}
	}
	return 0;
}

上一题