SPOJ 227 Ordering the Soldiers 线段树 / 树状数组
题意:设原数组为a[i],pos[i]代表第 i 个位置之前有多少个数比a[i]大,求原数组a[i]。
这个题意是看了别人的题解才明白,我自己没读出来……
方法:假设我们从左往右放,因为后面的数还有可能影响前面的数的位置,所以在最后一个数放完之前,我们没法确定每个数的位置,所以我们反过来考虑,从右往左放。因为每个数前面比它大的数的个数pos[i]已知,我们可以不必关心这些数的具体数值,从而转化为它从右往左走了多少个空格,即pos[i]个,因此这个数放在第 pos[i] + 1 个空格位置上。这个空格所在位置的下标id,即是a[i]。a[i] = id;
树状数组或线段树记录区间[1, i ]的空格个数,对于放好的数,相应区间的空格数减1。
树状数组代码:5360 ms
#include <cstdio>
#include <cstring>
#include <cstdlib> const int MAXN = ; int pos[MAXN];
int C[MAXN];
int ans[MAXN];
bool vis[MAXN];
int N; int lowbit( int x )
{
return x&(-x);
} void Add( int x, int val )
{
while ( x <= N )
{
C[x] += val;
x += lowbit(x);
}
return;
} int Query( int x )
{
int res = ;
while ( x > )
{
res += C[x];
x -= lowbit(x);
}
return res;
} //注意二分查找的写法,不然很容易死循环
void BiSearch( int l, int r, int val, int &addr )
{
int mid;
while ( l <= r )
{
mid = ( l + r ) >> ;
int sum = Query( N ) - Query( mid - );
//printf( "mid=%d sum=%d\n", mid, sum );
if ( sum > val ) l = mid + ;
else
{
if ( sum == val )
{
if ( !vis[mid] ) //需要特殊判断一下这个点之前是否已经放好了
{
addr = mid;
r = mid - ;
}
else
{
l = mid + ;
}
}
else r = mid - ;
}
}
return;
} int main()
{
int T;
scanf( "%d", &T );
while ( T-- )
{
scanf( "%d", &N );
memset( C, , sizeof(int)*( N + ) );
memset( vis, false, sizeof(bool)*( N + ) );
for ( int i = ; i <= N; ++i )
{
scanf( "%d", &pos[i] );
Add( i, );
} for ( int i = N; i > ; --i )
{
int id;
BiSearch( , N, pos[i] + , id );
ans[i] = id;
vis[id] = true;
//printf( "id = %d\n", id );
Add( id, - );
}
printf( "%d", ans[] );
for ( int i = ; i <= N; ++i )
printf( " %d", ans[i] );
puts("");
}
return ;
}
线段树代码:1840 ms
#include <cstdio>
#include <cstring>
#include <cstdlib> #define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1 const int MAXN = ; int pos[MAXN];
int sum[MAXN << ];
int ans[MAXN];
int N, id; void build( int l, int r, int rt )
{
sum[rt] = r - l + ;
if ( l == r ) return; int m = ( l + r ) >> ;
build( lson );
build( rson );
return;
} void Update( int po, int l, int r, int rt )
{
--sum[rt];
if ( l == r )
{
id = l;
return;
} int m = ( l + r ) >> ; if ( po <= sum[rt << ] ) Update( po, lson );
else Update( po - sum[rt << ], rson ); return;
} int main()
{
int T;
scanf( "%d", &T );
while ( T-- )
{
scanf( "%d", &N );
build( , N, );
for ( int i = ; i <= N; ++i )
scanf( "%d", &pos[i] ); for ( int i = N; i > ; --i )
{
Update( pos[i] + , , N, );
ans[i] = N - id + ;
}
printf( "%d", ans[] );
for ( int i = ; i <= N; ++i )
printf( " %d", ans[i] );
puts("");
}
return ;
}
SPOJ 227 Ordering the Soldiers 线段树 / 树状数组的更多相关文章
- SPOJ 227 Ordering the Soldiers
As you are probably well aware, in Byteland it is always the military officer's main worry to order ...
- HDOJ 4417 - Super Mario 线段树or树状数组离线处理..
题意: 同上 题解: 抓着这题作死的搞~~是因为今天练习赛的一道题.SPOJ KQUERY.直到我用最后一种树状数组通过了HDOJ这题后..交SPOJ的才没超时..看排名...时间能排到11名了..有 ...
- CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)
The best programmers of Embezzland compete to develop a part of the project called "e-Governmen ...
- 树状数组求第K小值 (spoj227 Ordering the Soldiers && hdu2852 KiKi's K-Number)
题目:http://www.spoj.com/problems/ORDERS/ and pid=2852">http://acm.hdu.edu.cn/showproblem.php? ...
- 【 SPOJ - GRASSPLA】 Grass Planting (树链剖分+树状数组)
54 种草约翰有 N 个牧场,编号为 1 到 N.它们之间有 N − 1 条道路,每条道路连接两个牧场.通过这些道路,所有牧场都是连通的.刚开始的时候,所有道路都是光秃秃的,没有青草.约翰会在一些道 ...
- SPOJ DQUERY树状数组离线or主席树
D-query Time Limit: 227MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Submit Status ...
- 小结:线段树 & 主席树 & 树状数组
概要: 就是用来维护区间信息,然后各种秀智商游戏. 技巧及注意: 一定要注意标记的下放的顺序及影响!考虑是否有叠加或相互影响的可能! 和平衡树相同,在操作每一个节点时,必须保证祖先的tag已经完全下放 ...
- SPOJ 3267 D-query(离散化+在线主席树 | 离线树状数组)
DQUERY - D-query #sorting #tree English Vietnamese Given a sequence of n numbers a1, a2, ..., an and ...
- [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
随机推荐
- Excel下用SQL语句实现AVEDEV函数功能
Excel下AVEDEV函数返回一组数据点到其算术平均值的绝对偏差的平均值. AVEDEV 是对一组数据中变化性的度量.最常见的应用就是统计平均分差. 但是如果在Excel中写SQL进行一些复杂的统计 ...
- Portion of class Throwable’s inheritance hierarchy
- 手机开发Android模拟器genymotion
手机开发的时候总会碰到一个问题,eclipse插件自带的android模拟器太慢了. 根据网络上有人推荐使用genymotion模拟器. 主要的操作步骤如下: 1.在genymotion网站注册账 ...
- 8大排序算法图文讲解 分类: Brush Mode 2014-08-18 11:49 78人阅读 评论(0) 收藏
排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 常见的内部排序算法有:插入排序.希尔排序. ...
- Phyre LCUE with YEBIS cause issues about GS
when LCUE enabled in phyreEngine when Yebis integrated and render there are two mainloopdraws in one ...
- load d3dcompiler_46.dll failed
https://gist.github.com/rygorous/7936047 编shader的时候遇到这个warning不知道是不是什么隐患..从今天开始要做新项目了 尝试从同事那里要了这dll ...
- The Brain vs Deep Learning Part I: Computational Complexity — Or Why the Singularity Is Nowhere Near
The Brain vs Deep Learning Part I: Computational Complexity — Or Why the Singularity Is Nowhere Near ...
- HDU1004 Let the Balloon Rise(map的简单用法)
Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- js调试-定位到函数所在文件位置
原文:http://www.cnblogs.com/52cik/p/js-console-show-source.html 在控制台输入要查找的函数名如votePost 然后回车: 函数源码粗显啦,并 ...
- Office 2013 note
1.每次打开重新配置: 问题表现:启动后发现每次打开都会出现“正在配置”的进度 执行:reg add HKCU\Software\Microsoft\Office\15.0\Word\Options ...