Ordering the Soldiers 题解
2024-09-05 17:24:22
简化题意:
\(n\) 个人排队,给定每个人需要向左移动几个,求最终排列。
即还原逆序对。
错误想法
既然知道每个人向左移动 \(a_i\) 个,那就相当于让他的排名 \(-a_i\),他前面 \(a_i\) 个人的排名 \(+1\),差分即可。
问题在于他前面的 \(a_i\) 应是前面的人排好后的后 \(a_i\) 个,直接差分则是原序列中的。
sol
考虑倒着做。最后一个人的排名显然是 \(n-a_n\),则第 \(n-1\) 个人则是剩余排名中第 \(n-1-a_{n-1}\) 小的,以此类推。
正确性:分两类:第 \(n\) 个人是否对第 \(n-1\) 个人有影响易证。
code
const int N = 2e6+5;
int T,n;
int a[N],b[N];
#define lb(x) (x&-x)
struct BIT {
int t[N],n,l;
void add(int i,int x){for(;i<=n;i+=lb(i))t[i]+=x;}
int kth(int k) { // 权值BIT求第k大
int res = 0;
for(int i = l; ~i; --i) {
res += 1<<i;
if( res > n || k-t[res] <= 0 ) res -= 1<<i;
else k -= t[res];
}
return res+1;
}
} bit;
#undef lb
int main() {
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
read(T);
while( T-- ) {
read(n);
bit.n = n;
for(bit.l = 1; (1<<bit.l+1) <= n; ++bit.l);
For(i,1,n) read(a[i]), bit.add(i,1);
for(int i = n; i; --i) {
b[i] = bit.kth(i-a[i]);
bit.add(b[i],-1);
}
For(i,1,n) printf("%d ",b[i]);
putchar(10);
}
return 0;
}
最新文章
- java之多线程 一
- java反射详解(转)
- NFV技术中遇到的新名词
- Kettle6使用
- ascii codec can&#39;t decode byte 0xe8 in position 0:ordinal not in range(128)
- Android无法调用JS的问题解决
- Contest2037 - CSU Monthly 2013 Oct (problem A :Small change)
- 傲游浏览器4,傲游浏览器5如何一键批量打开url链接。
- oracle 12c 三学习 pdb 可插拔测试
- 黑马程序员:Java基础总结----正则表达式
- nginx trouble shooting
- Mybatis自定义分布式二级缓存实现与遇到的一些问题解决方案!
- Selective Search for Object Recognition(理解)
- swift函数的调用约定
- cmake使用笔记
- Apached+resin服务搭建
- MySql&#160;利用crontab实现MySql定时任务
- ES module 实现方式
- Error:Cannot access first() element from an empty List
- python爬虫之requests模块