• 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;
    }
  • 相关阅读:
    微信nickname乱码(emoji)及mysql编码格式设置(utf8mb4)解决的过程
    eclipse Specified VM install not found: type Standard VM, name
    eclipse中安装Open Explorer
    关于Java变量的可见性问题
    Win8&Win2012R2如何支持DOTA2输入法
    Adobe Flash player 10 提示:Error#2044:未处理的IOErrorEvent. text=Error#2036:加载未完成 的解决方法
    IntelliJ IDEA 12.1.4 解决中文乱码
    Win8.1RTM英文版安装中文语言包的两种方法
    在FlashDevelop里使用1.8版本的的TortoiseSVN
    [修复Win8.1 BUG] 解决Win8.1英文字体发虚不渲染问题
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/7194342.html
Copyright © 2020-2023  润新知