POJ 2828 Buy Tickets&POJ 2299 Ultra-QuickSort
2017-07-06 21:08
387 查看
POJ 2828 Buy Tickets
线段树基本应用
传送门:HustOJPOJ2299
题意
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; }
相关文章推荐
- poj 2299 Ultra-QuickSort 归并排…
- poj 2299 Ultra-QuickSort(求逆序对)&& poj 1804
- POJ 2299 Ultra-QuickSort【逆序数&&离散化】
- 【POJ】2299 - Ultra-QuickSort(离散化 & (树状数组 | 线段树))
- POJ_2299_Ultra-QuickSort & NYOJ_117_求逆序数
- POJ 2299 && ZOJ 2386 Ultra-QuickSort 线段树
- POJ 2299, Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort
- 【原】 POJ 2299 Ultra-QuickSort 逆序数 解题报告
- poj 2299 Ultra-QuickSort 求逆序对,树状数组和归并排序
- zoj 2386 || poj 2299 Ultra-QuickSort
- [普及] 求序列中逆序对的个数 [poj 2299 Ultra-QuickSort]
- poj 2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort 归并排序
- poj 2299 Ultra-QuickSort 归并排序求解逆序对
- POJ 2299 Ultra-QuickSort (归并排序求逆序对数)
- POJ2299 Ultra-QuickSort(归并排序)
- POJ 2299 Ultra-QuickSort