题意:设原数组为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. Word图片版式设置问题

    word里面插入图片,版式设置为嵌入式,又显示不完整:设置上下,图片又跑到页面上方空白处.无论怎么设置,都不满意. 以为是word的问题,后来网络搜索才发现,如果段落行距为固定值的话,图片改为嵌入型后 ...

  2. 【BZOJ】【1005】【HNOI2008】明明的烦恼

    Prufer序列/排列组合+高精度 窝不会告诉你我是先做了BZOJ1211然后才来做这题的>_>(为什么?因为我以前不会高精度呀……) 在A了BZOJ 1211和1089之后,蒟蒻终于有信 ...

  3. 我的这10年——从机械绘图 到 炼油 到 微软MVP 的华丽转身

    年底了,各种总结计划满天飞,有空的时候我也一直在思考这么多年,是怎么过来的.也曾经很迷茫,希望经验和经历能给大家一点带来一点正能量的东西.10年很长,10年前说实话我没有思考过现在的样子,但10年前的 ...

  4. 寒假222_Topcoder SRM648

    序号1: A,随便模拟好了,最后30秒发现一个都比的错误,无奈输错格式. 2: B,问你出去两个点,以及所产生的边 问你:产生多的联通快 加答案加1. 数据小,随便写暴力 3: copy思路. 我们先 ...

  5. POJ 1700 Crossing River (贪心)

    Crossing River Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 9585 Accepted: 3622 Descri ...

  6. JobClient学习------作业提交与初始化

    public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); ...

  7. POJ 2923 Relocation (状态压缩,01背包)

    题意:有n个(n<=10)物品,两辆车,装载量为c1和c2,每次两辆车可以运一些物品,一起走.但每辆车物品的总重量不能超过该车的容量.问最少要几次运完. 思路:由于n较小,可以用状态压缩来求解. ...

  8. 刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第六章 1(Lists)

    127 - "Accordian" Patience 题目大意:一个人一张张发牌,如果这张牌与这张牌前面的一张或者前面的第三张(后面称之为一位置和三位置)的点数或花式相同,则将这张 ...

  9. JS获取Url参数的通用方法

    //获取URL中的参数 function request(paras) { var url = location.href.replace('#', ''); var paraString = url ...

  10. ExtJs之文本框及数字输入

    结合HTML来理解, 比较容易. <!DOCTYPE html> <html> <head> <title>ExtJs</title> &l ...