您的位置:首页 > 产品设计 > UI/UE

POJ 2828 Buy Tickets&POJ 2299 Ultra-QuickSort

2017-07-06 21:08 387 查看

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=500007;
const int oo=0x3f3f3f3f;
typedef long long LL;
const LL loo=4223372036854775807ll;
typedef long double LB;
const LL mod=1e9+7;
const double eps=1e-6;
struct SegmentTree
{
LL sum;
}stree[4*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<<1].sum+stree[rt<<1|1].sum;
}
void build(int l, int r, int rt)
{
if(l==r)
{
stree[rt].sum=0;
return;
}
int m=(l+r)>>1;
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)>>1;
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)>>1;
int res=0;
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!=0)
{
for(int i=1;i<=n;i++)
{
num[i].i=i;
cin>>num[i].val;
}
sort(num+1, num+1+n, cmp1);
for(int i=1;i<=n;i++)
{
num[i].hash=i;
}
sort(num+1, num+1+n, cmp2);
build(1, n, 1);
LL res=0;
for(int i=1;i<=n;i++)
{
res+=query(num[i].hash, n, 1, n, 1);
change(num[i].hash, 1, n, 1);
}
cout<<res<<endl;
}

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


插队

#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=200007;
const int oo=0x3f3f3f3f;
typedef long long LL;
const LL loo=4223372036854775807ll;
typedef long double LB;
const LL mod=1e9+7;
const double eps=1e-6;
struct SegmentTree
{
LL sum;
}stree[4*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<<1].sum+stree[rt<<1|1].sum;
}
void build(int l, int r, int rt)
{
if(l==r)
{
stree[rt].sum=1;
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
int change(int pos, int l, int r, int rt)
{
if(l==r)
{
stree[rt].sum=0;
return l;
}
int m=(l+r)>>1;
int ret=0;
if(stree[rt<<1].sum>=pos) ret=change(pos, lson);
else ret=change(pos-stree[rt<<1].sum, rson);
pushup(rt);
return ret;
}
int main(int argc, char *argv[])
{
_;
int n;
while(cin>>n)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&num[i].pos);
num[i].pos++;
scanf("%lld",&num[i].val);
}

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

//system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: