CodeChef:ORDERS

简化题意:

\(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;
}

最新文章

  1. java之多线程 一
  2. java反射详解(转)
  3. NFV技术中遇到的新名词
  4. Kettle6使用
  5. ascii codec can&#39;t decode byte 0xe8 in position 0:ordinal not in range(128)
  6. Android无法调用JS的问题解决
  7. Contest2037 - CSU Monthly 2013 Oct (problem A :Small change)
  8. 傲游浏览器4,傲游浏览器5如何一键批量打开url链接。
  9. oracle 12c 三学习 pdb 可插拔测试
  10. 黑马程序员:Java基础总结----正则表达式
  11. nginx trouble shooting
  12. Mybatis自定义分布式二级缓存实现与遇到的一些问题解决方案!
  13. Selective Search for Object Recognition(理解)
  14. swift函数的调用约定
  15. cmake使用笔记
  16. Apached+resin服务搭建
  17. MySql&#160;利用crontab实现MySql定时任务
  18. ES module 实现方式
  19. Error:Cannot access first() element from an empty List
  20. python爬虫之requests模块

热门文章

  1. 嵌套div的onClick事件问题
  2. 自建简易FaaS平台
  3. azure获取vm运行状态
  4. Netty基础招式——ChannelHandler的最佳实践
  5. 小程序中多个echarts折线图在同一个页面的使用
  6. Android开发失业六个月了,无限的焦虑
  7. OpenStack虚拟网络与物理网络的衔接(flat方式)
  8. Apache/Nginx/IIS日志记录的各个字段内容与含义
  9. 蓝桥杯练习-各大OJ平台介绍
  10. AWD比赛组织指南