题目传送门

题意:n头牛,1~n的id给它们乱序编号,已知每头牛前面有多少头牛的编号是比它小的,求原来乱序的编号

分析:从后往前考虑,最后一头牛a[i] = 0,那么它的编号为第a[i] + 1编号:为1,倒数第二头牛的编号为除去最后一头牛的编号后的第a[i-1] + 1编号:为3,其他的类推,所以可以维护之前已经选掉的编号,求第k大的数字,sum[rt] 表示该区间已经被选掉的点的个数。另外树状数组也可以做,只不过用二分优化查找第k大的位置。

收获:逆向思维,求动态第K大

代码(线段树):

/************************************************
* Author :Running_Time
* Created Time :2015/9/9 星期三 17:01:08
* File Name :P.cpp
************************************************/ #include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std; #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 8e3 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
struct ST {
int sum[N<<2];
void build(int l, int r, int rt) {
sum[rt] = 0;
if (l == r) return ;
int mid = (l + r) >> 1;
build (lson);
build (rson);
}
int query(int p, int l, int r, int rt) {
sum[rt]++;
if (l == r) return l;
int mid = (l + r) >> 1;
int tmp = mid - l + 1 - sum[rt<<1];
if (tmp >= p) return query (p, lson);
else {
return query (p - tmp, rson);
}
}
}st;
int a[N], ans[N]; int main(void) {
int n;
while (scanf ("%d", &n) == 1) {
a[1] = 0;
for (int i=2; i<=n; ++i) {
scanf ("%d", &a[i]);
}
st.build (1, n, 1);
for (int i=n; i>=1; --i) {
ans[i] = st.query (a[i] + 1, 1, n, 1);
}
for (int i=1; i<=n; ++i) {
printf ("%d\n", ans[i]);
}
} return 0;
}

  

代码(树状数组):

/************************************************
* Author :Running_Time
* Created Time :2015/9/9 星期三 18:19:28
* File Name :P_BIT.cpp
************************************************/ #include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std; #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 8e3 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int n;
struct BIT {
int c[N];
void init(void) {
memset (c, 0, sizeof (c));
}
void updata(int i, int x) {
while (i <= n) {
c[i] += x; i += i & (-i);
}
}
int query(int i) {
int ret = 0;
while (i) {
ret += c[i]; i -= i & (-i);
}
return ret;
}
int bsearch(int l, int r, int k) {
while (l <= r) {
int mid = (l + r) >> 1;
if (mid - query (mid) >= k) r = mid - 1;
else l = mid + 1;
}
return l;
}
}bit;
int a[N], ans[N]; int main(void) {
while (scanf ("%d", &n) == 1) {
a[1] = 0;
for (int i=2; i<=n; ++i) scanf ("%d", &a[i]);
bit.init ();
for (int i=n; i>=1; --i) {
ans[i] = bit.bsearch (1, n, a[i] + 1);
bit.updata (ans[i], 1);
}
for (int i=1; i<=n; ++i) {
printf ("%d\n", ans[i]);
}
} return 0;
}

  

最新文章

  1. jQuery九类选择器详解
  2. 在Navicat premium上创建的SQL Server数据库,实现用PHP连接(即php连接微软MSSQL)
  3. zabbix3.x搭建(1)
  4. 好用的SQLSERVER数据库自动备份工具SQLBackupAndFTP(功能全面)
  5. connect函数详解
  6. open_clientfd(char* hostname,int port)和open_listenfd(int port)
  7. Android中库项目、jar包等的使用方法
  8. java反射机制性能优化
  9. 老李推荐:第6章3节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-命令翻译类
  10. websocket学习和使用
  11. sdk&amp;jdk&amp;jre
  12. window.history.go(-1)返回且刷新页面
  13. apache-jmeter-5.0的简单压力测试使用方法
  14. Windows API 调用示例
  15. k8s--如何使用Namespaces
  16. thinkcmf 相关
  17. Python属性(@property)
  18. Linux设备驱动剖析之IIC(二)
  19. TCHAR函数查询
  20. llg的农场(farm)

热门文章

  1. Swift中字符串转化为Class的方法
  2. db_create_file_dest
  3. Android cookies正确的更新方式
  4. Hadoop中序列化与Writable接口
  5. RK3288 GPIO 输出问题【转】
  6. ⭐register_chrdev、register_chrdev_region以及alloc_chrdev_region之间的区别
  7. chrome——关于chrome浏览器的奇葩问题
  8. jsp项目上传到服务器
  9. c语言中为什么左移不分符号数无符号数,而右移分呢??
  10. SPOJ:Ada and Graft (set合并&amp;优化)