天天看點

POJ 2828 Buy Tickets&POJ 2299 Ultra-QuickSortPOJ 2828 Buy Tickets

POJ 2828 Buy Tickets

線段樹基本應用

傳送門:HustOJ

POJ2299

題意

2828

排隊買票時候插隊。

給出一些數對,分别代表某個人的想要插入的位置Pos_i和他的Val_i,求出最後的隊列的val順序

2299

求逆序對數量

思路

兩個題都不難,都是線段樹基本應用。

逆序對從前往後處理,遇到一個數,就查詢比他大還在他前面出現的數的個數。是以線段樹維護出現過的數。又因為資料範圍是999999999,是以需要hash一下。先排個序,标記1~n,再恢複原序。對于每個數i的hash[i],查詢[hash[i],n]有多少個數出現過。線段樹記錄1到n出現過的數,出現一次就加一,維護區間和,即出現過的次數。

插隊問題,注意到後面的人的要求總能被滿足,先從後面處理。而後面的人會擠前面的人,是以從後網前處理時,比如某人想進k位置,實際上是從前往後數k個空位,就是他的實際位置。線段樹開始置1,表示有空位,維護和,表示區間的空位數。插入時,如果左兒子空位夠,那麼插入左兒子;否則減左側空位數,插入右兒子。

代碼

逆序對

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <iomanip>
#define _ ios_base::sync_with_stdio(0),cin.tie(0)
#define M(a,b) memset(a,b,sizeof(a))
#define N n
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;

const int MAXN=;
const int oo=;
typedef long long LL;
const LL loo=l;
typedef long double LB;
const LL mod=+;
const double eps=;
struct SegmentTree
{
    LL sum;
}stree[*MAXN];
struct Num
{
    LL val;
    int i;
    int hash;
}num[MAXN];
bool cmp1(Num a, Num b)
{
    return a.val<b.val;
}
bool cmp2(Num a, Num b)
{
    return a.i<b.i;
}
void pushup(int rt)
{
    stree[rt].sum=stree[rt<<].sum+stree[rt<<|].sum;
}
void build(int l, int r, int rt)
{
    if(l==r)
    {
        stree[rt].sum=;
        return;
    }
    int m=(l+r)>>;
    build(lson);
    build(rson);
    pushup(rt);
}
void change(int pos, int l, int r, int rt)
{
    if(l==r)
    {
        stree[rt].sum++;
        return;
    }
    int m=(l+r)>>;
    if(pos<=m) change(pos, lson);
    else change(pos, rson);
    pushup(rt);
}
LL query(int L, int R, int l, int r, int rt)
{
    if(L<=l&&r<=R) return stree[rt].sum;

    int m=(l+r)>>;
    int res=;
    if(L<=m) res+=query(L, R, lson);
    if(m<R) res+=query(L, R, rson);
    return res;
}
int main(int argc, char *argv[])
{
    _;
    int n;
    while(cin>>n&&n!=)
    {
        for(int i=;i<=n;i++)
        {
            num[i].i=i;
            cin>>num[i].val;
        }
        sort(num+, num++n, cmp1);
        for(int i=;i<=n;i++)
        {
            num[i].hash=i;
        }
        sort(num+, num++n, cmp2);
        build(, n, );
        LL res=;
        for(int i=;i<=n;i++)
        {
            res+=query(num[i].hash, n, , n, );
            change(num[i].hash, , n, );
        }
        cout<<res<<endl;
    }

    //system("pause");
    return ;
}
           

插隊

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <iomanip>
#define _ ios_base::sync_with_stdio(0),cin.tie(0)
#define M(a,b) memset(a,b,sizeof(a))
#define N n
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;

const int MAXN=;
const int oo=;
typedef long long LL;
const LL loo=l;
typedef long double LB;
const LL mod=+;
const double eps=;
struct SegmentTree
{
    LL sum;
}stree[*MAXN];
struct Num
{
    LL val;
    int hash;
    int pos;
}num[MAXN];
bool cmp1(Num a, Num b)
{
    return a.hash<b.hash;
}
void pushup(int rt)
{
    stree[rt].sum=stree[rt<<].sum+stree[rt<<|].sum;
}
void build(int l, int r, int rt)
{
    if(l==r)
    {
        stree[rt].sum=;
        return;
    }
    int m=(l+r)>>;
    build(lson);
    build(rson);
    pushup(rt);
}
int change(int pos, int l, int r, int rt)
{
    if(l==r)
    {
        stree[rt].sum=;
        return l;
    }
    int m=(l+r)>>;
    int ret=;
    if(stree[rt<<].sum>=pos) ret=change(pos, lson);
    else ret=change(pos-stree[rt<<].sum, rson);
    pushup(rt);
    return ret;
}
int main(int argc, char *argv[])
{
    _;
    int n;
    while(cin>>n)
    {
        for(int i=;i<=n;i++)
        {
            scanf("%d",&num[i].pos);
            num[i].pos++;
            scanf("%lld",&num[i].val);
        }

        build(, n, );
        for(int i=n;i>=;i--)
        {
            num[i].hash=change(num[i].pos, , n, );
        }
        sort(num+, num++n,cmp1);
        for(int i=;i<=n;i++)
        {
            printf("%lld%c",num[i].val,i==n ? '\n' : ' ');
        }
    }

    //system("pause");
    return ;
}
           

繼續閱讀