• codeforces 830 B. Cards Sorting(线段树)


    题目链接:http://codeforces.com/contest/830/problem/B

    题解:其实这题就是求当前大小的数到下一个大小的数直接有多少个数,这时候可以利用数据结构来查询它们之间有几个数优先往后面找如果后面没了再轮到前面找。可以开始将每个数的下表定为1然后拿掉之后就为0然后两值之间有几个数就用区间求和来求。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #define inf 0X3f3f3f3f
    using namespace std;
    const int M = 1e5 + 10;
    typedef long long ll;
    int a[M] , b[M];
    struct TGP {
        int Min , pos;
        TGP() {}
        TGP(int Min , int pos):Min(Min), pos(pos) {}
    };
    struct TnT {
        int l , r , sum;
        TGP gp;
    }T[M << 2];
    void push_up(int i) {
        T[i].sum = T[i << 1].sum + T[(i << 1) | 1].sum;
        if(T[i << 1].gp.Min <= T[(i << 1) | 1].gp.Min) {
            T[i].gp = T[i << 1].gp;
        }
        else T[i].gp = T[(i << 1) | 1].gp;
    }
    void build(int l , int r , int i) {
        int mid = (l + r) >> 1;
        T[i].l = l , T[i].r = r;
        if(l == r) {
            T[i].gp.Min = a[l];
            T[i].gp.pos = l;
            T[i].sum = 1;
            return ;
        }
        build(l , mid , i << 1);
        build(mid + 1 , r , (i << 1) | 1);
        push_up(i);
    }
    void update(int pos , int i) {
        int mid = (T[i].l + T[i].r) >> 1;
        if(T[i].l == T[i].r && T[i].l == pos) {
            T[i].gp.Min = inf;
            T[i].sum = 0;
            return ;
        }
        if(pos > mid) update(pos , (i << 1) | 1);
        else update(pos , i << 1);
        push_up(i);
    }
    TGP query(int l , int r , int i) {
        int mid = (T[i].l + T[i].r) >> 1;
        if(T[i].l == l && T[i].r == r) {
            return T[i].gp;
        }
        if(mid < l) return query(l , r , (i << 1) | 1);
        else if(mid >= r) return query(l , r , i << 1);
        else {
            TGP a1 = query(l , mid , i << 1) , a2 = query(mid + 1 , r , (i << 1) | 1);
            if(a1.Min > a2.Min) return a2;
            else return a1;
        }
    }
    int getsum(int l , int r , int i) {
        int mid = (T[i].l + T[i].r) >> 1;
        if(T[i].l == l && T[i].r == r) {
            return T[i].sum;
        }
        if(mid < l) return getsum(l , r , (i << 1) | 1);
        else if(mid >= r) return getsum(l , r , i << 1);
        else return getsum(l , mid , i << 1) + getsum(mid + 1 , r , (i << 1) | 1);
    }
    int main() {
        int n;
        scanf("%d" , &n);
        for(int i = 1 ; i <= n ; i++) scanf("%d" , &a[i]) , b[i] = a[i];
        sort(b + 1 , b + n + 1);
        build(1 , n , 1);
        ll ans = 0;
        int now = 1;
        for(int i = 1 ; i <= n ; i++) {
            TGP gg = query(now , n , 1);
            //cout << gg.Min << ' ' << gg.pos << endl;
            if(gg.Min == b[i]) {
                ans += getsum(now , gg.pos , 1);
                //cout << "ans: " << ans << endl;
                now = gg.pos + 1;
                if(now > n) now = 1;
                update(gg.pos , 1);
            }
            else {
                TGP gb = query(1 , now , 1);
                //cout << gb.Min << ' ' << gb.pos << endl;
                if(gb.Min == b[i]) {
                    ans += getsum(now , n , 1);
                    ans += getsum(1 , gb.pos , 1);
                    now = gb.pos + 1;
                    if(now > n) now = 1;
                    update(gb.pos , 1);
                }
            }
        }
        printf("%lld
    " , ans);
        return 0;
    }
  • 相关阅读:
    Java LinkedList 源码剖析
    Java并发编程:线程池的使用
    Java 线程池的原理与实现
    多线程JAVA篇(一)
    软件开发中会用到的图
    linux文件名匹配——通配符使用
    XModem协议
    dmesg 命令七种用法
    定位精度单位CEP、RMS、2DRMS常识
    5G NR 技术简介
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/7194342.html
Copyright © 2020-2023  润新知