蓝桥杯双向排序java AC啦


import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        int m = scan.nextInt();
        Integer[] a = new Integer[N+1];
        for(int i=1;i<=N;i++) {
            a[i] = i;
        }
        SegmentTree1 segment = new SegmentTree1(N);
        int[] count = new int[1];
        for(int i=0;i<m;i++) {
            int kind = scan.nextInt();
            int pos = scan.nextInt(); 
            if(kind == 0) {
                int need = pos - N + segment.search(1, 1, N);
                if(need <= 0) continue;
                else {
                    count[0] = need;
                    segment.change1(1, -1, count);
                }
            }
            if(kind == 1) {
                int need = N - pos + 1 - segment.search(1, 1, N);
                if(need <= 0) continue;
                else {
                    count[0] = need;
                    segment.change0(1, 1, count);
                }
            }
        }
        scan.close();
        int[] vis = new int[N+1];
        for(int i = N;i>=1;i--) {
            if(segment.search(1, i, i) == 0) System.out.print(a[i] + " ");
            else vis[i] = 1;
        }
        for(int i = 1;i<=N;i++) {
            if(vis[i] == 1) System.out.print(a[i] + " ");
        }
    }
}

class SegmentTree1{
    Node root;
    Node[] tree;
    int N;
    private class Node{
        int left,right;
        int sum;
        int lz;
        public Node(int left,int right) {
            this.left = left;
            this.right = right;
            sum = 0;
        }
        public Node() {
            
        }
    }
    public SegmentTree1(int N) {
        this.N = N;
        tree = new Node[4*N+1];
        for(int i=1;i<=4*N;i++) {
            tree[i] = new Node();
        }
        build(1,1,N);
    }
    public void build(int n,int l,int r) {
        if(l == r) {
            tree[n] = new Node(l,r);
            tree[n].sum = 1;
            return ;
        }
        tree[n] = new Node(l,r);
        int mid = l + (r - l)/2;
        build(2*n,l,mid);
        build(2*n+1,mid+1,r);
        tree[n].sum = tree[2*n].sum + tree[2*n+1].sum;
        return ;
    }
    public void change0(int n,int k,int[] count) {
        if(count[0] == 0) return ;
        if(tree[n].sum == 0 && count[0] >= tree[n].right - tree[n].left + 1) {
            tree[n].lz += k;
            tree[n].sum += k*(tree[n].right - tree[n].left + 1);
            count[0] -= tree[n].right - tree[n].left + 1;
            return ;
        }
        if(tree[n].left == tree[n].right) return ;
        pushdown(n);
        if(tree[2*n].sum != tree[2*n].right - tree[2*n].left + 1) change0(2*n,k,count);
        if(tree[2*n+1].sum != tree[2*n+1].right - tree[2*n+1].left + 1) change0(2*n+1,k,count);
        tree[n].sum = tree[2*n].sum + tree[2*n+1].sum;
        return ;
    }
    public void change1(int n,int k,int[] count) {
        if(count[0] == 0) return ;
        if(tree[n].sum == tree[n].right - tree[n].left + 1 && count[0] >= tree[n].right - tree[n].left + 1) {
            tree[n].lz += k;
            tree[n].sum += k*(tree[n].right - tree[n].left + 1);
            count[0] -= tree[n].right - tree[n].left + 1;
            return ;
        }
        if(tree[n].left == tree[n].right) return ;
        pushdown(n);
        if(tree[2*n].sum != 0) change1(2*n,k,count);
        if(tree[2*n+1].sum != 0) change1(2*n+1,k,count);
        tree[n].sum = tree[2*n].sum + tree[2*n+1].sum;
        return ;
    }
    public void pushdown(int n) {
        if(tree[n].lz != 0) {
            tree[2*n].lz += tree[n].lz;
            tree[2*n+1].lz += tree[n].lz;
            int mid = tree[n].left + (tree[n].right - tree[n].left)/2;
            tree[2*n].sum += tree[n].lz*(mid - tree[2*n].left + 1);
            tree[2*n+1].sum += tree[n].lz*(tree[2*n+1].right - mid);
            tree[n].lz = 0;
        }
    }
    public int search(int n,int i,int j) {
        if(tree[n].left >= i && tree[n].right <= j) {
            return tree[n].sum;
        }
        if(tree[n].left > j || tree[n].right < i) return 0;
        pushdown(n);
        int t = 0;
        if(tree[2*n].right >= i) t += search(2*n,i,j);
        if(tree[2*n+1].left <= j) t += search(2*n+1,i,j);
        return t;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值