题意:设原数组为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 线段树 / 树状数组的更多相关文章

  1. SPOJ 227 Ordering the Soldiers

    As you are probably well aware, in Byteland it is always the military officer's main worry to order ...

  2. HDOJ 4417 - Super Mario 线段树or树状数组离线处理..

    题意: 同上 题解: 抓着这题作死的搞~~是因为今天练习赛的一道题.SPOJ KQUERY.直到我用最后一种树状数组通过了HDOJ这题后..交SPOJ的才没超时..看排名...时间能排到11名了..有 ...

  3. CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)

    The best programmers of Embezzland compete to develop a part of the project called "e-Governmen ...

  4. 树状数组求第K小值 (spoj227 Ordering the Soldiers &amp;&amp; hdu2852 KiKi&#39;s K-Number)

    题目:http://www.spoj.com/problems/ORDERS/ and pid=2852">http://acm.hdu.edu.cn/showproblem.php? ...

  5. 【 SPOJ - GRASSPLA】 Grass Planting (树链剖分+树状数组)

    54  种草约翰有 N 个牧场,编号为 1 到 N.它们之间有 N − 1 条道路,每条道路连接两个牧场.通过这些道路,所有牧场都是连通的.刚开始的时候,所有道路都是光秃秃的,没有青草.约翰会在一些道 ...

  6. SPOJ DQUERY树状数组离线or主席树

    D-query Time Limit: 227MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Submit Status ...

  7. 小结:线段树 & 主席树 & 树状数组

    概要: 就是用来维护区间信息,然后各种秀智商游戏. 技巧及注意: 一定要注意标记的下放的顺序及影响!考虑是否有叠加或相互影响的可能! 和平衡树相同,在操作每一个节点时,必须保证祖先的tag已经完全下放 ...

  8. SPOJ 3267 D-query(离散化+在线主席树 | 离线树状数组)

    DQUERY - D-query #sorting #tree English Vietnamese Given a sequence of n numbers a1, a2, ..., an and ...

  9. [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

随机推荐

  1. Entity Framework 学习之--Ling to entity实现分页

    最近用MVC做的一个项目涉及到分页,中间用了entity framework来查数据库,不用直接写sql语句,方便了很多. 一般分页的思路是获得两个变量的值: 1.一共有多少条记录 totalCoun ...

  2. Codeforces 343D Water Tree 分类: Brush Mode 2014-10-05 14:38 98人阅读 评论(0) 收藏

    Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each vertex is a res ...

  3. 4-Highcharts曲线图之时间轴折线图

    鼠标按住左键 左右移动可以试试<!DOCTYPE> <html lang='en'> <head> <title>4-Highcharts曲线图之时间轴 ...

  4. Codeforces Round #204 (Div. 2)->C. Jeff and Rounding

    C. Jeff and Rounding time limit per test 1 second memory limit per test 256 megabytes input standard ...

  5. 安装成功的nginx如何添加未编译安装模块

    原已经安装好的nginx,现在需要添加一个未被编译安装的模块举例说明:安装第三方的ngx_cache_purge模块(用于清除指定URL的缓存)nginx的模块是需要重新编译nginx,而不是像apa ...

  6. 【转载】Redis与Memcached的区别

    传统MySQL+ Memcached架构遇到的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量 ...

  7. WinHex分析PE格式(1)

    最近在一直努力学习破解,但是发现我的基础太差了,就想学习一下PE结构.可是PE结构里的结构关系太复杂,看这老罗的WiN32汇编最后一章 翻两页又合上了..把自己的信心都搞没了.感觉自己的理解能力不行, ...

  8. javascript设计模式--中介者模式(Mediator)

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 【三】php之梗

    1.php没有顶级作用域,所以你没办法在函数内部使用变量(参数传递除外,而且常量是可以的哟),所以你的变量即使是static的也不能在函数外声明函数里用.除非借助global关键字修饰变量才可以.但是 ...

  10. VMware 使用

    1.客户操作系统被禁用: BIOS中开启VT(Virtual Technology)