zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Notes about "Exploring Expect"
    Reuse Sonar Checkstyle Violation Report for Custom Data Analysis
    Eclipse带参数调试的方法
    MIT Scheme Development on Ubuntu
    Manage Historical Snapshots in Sonarqube
    U盘自动弹出脚本
    hg的常用配置
    Java程序员的推荐阅读书籍
    使用shared memory 计算矩阵乘法 (其实并没有加速多少)
    CUDA 笔记
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/7194342.html
Copyright © 2011-2022 走看看