传送门


题意:有一个长为\(n\)的排列\(p\),设\(S_i=\sum_{j=1}^{i-1}p_j\cdot[p_j<p_i]\),给出\(S\),要求还原出\(p\)。保证有解,\(n\leq 2\times 10^5\)。

考虑倒序将\(S\)还原为全\(0\)的序列,从小到大依次考虑插入每个数的影响。假设在位置\(x\)插入\(i\),显然此时\(S_x=0\),且会使得位置\(x\)右侧的每一个未插入数字的\(S_y\)都减去\(i\)。因此对于第\(i\)个数,唯一合法的位置就是所有\(S_x=0\)的位置中最右侧的那个。由于保证有解,维护最小值,在线段树上二分即可。

Code:

#include <cstdio>
#include <cctype>
#include <cassert>
#include <cstring>
#include <iostream>
#include <algorithm>
#define R register
#define ll long long
using namespace std;
const int N = 210000, K = N << 2;
const ll inf = 1e18; int n, lt[K], rt[K], p[N];
ll a[N], minVal[K], tag[K];
inline void pushdown(int); template <class T> inline void read(T &x) {
x = 0;
char ch = getchar(), w = 0;
while (!isdigit(ch))
w = (ch == '-'), ch = getchar();
while (isdigit(ch))
x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
x = w ? -x : x;
return;
} void build(int k) {
if (lt[k] == rt[k]) {
minVal[k] = a[lt[k]];
return;
}
int mid = (lt[k] + rt[k]) >> 1, l = k << 1, r = (k << 1) + 1;
lt[l] = lt[k], rt[l] = mid, lt[r] = mid + 1, rt[r] = rt[k];
build(l), build(r), minVal[k] = min(minVal[l], minVal[r]);
return;
} void modify(int k, int x, int y, ll w) {
if (lt[k] >= x && rt[k] <= y) {
minVal[k] += w, tag[k] += w;
return;
}
pushdown(k);
int mid = (lt[k] + rt[k]) >> 1, l = k << 1, r = (k << 1) + 1;
if (x <= mid) modify(l, x, y, w);
if (y > mid) modify(r, x, y, w);
minVal[k] = min(minVal[l], minVal[r]);
return;
} int query(int k) {
if (lt[k] == rt[k]) {
minVal[k] = inf;
return lt[k];
}
int l = k << 1, r = (k << 1) + 1, ret;
pushdown(k), ret = query(minVal[r] ? l : r);
minVal[k] = min(minVal[l], minVal[r]);
return ret;
} inline void pushdown(int k) {
int l = k << 1, r = (k << 1) + 1;
if (tag[k]) {
modify(l, lt[k], rt[k], tag[k]);
modify(r, lt[k], rt[k], tag[k]);
tag[k] = 0;
}
return;
} int main() {
read(n);
for (R int i = 1; i <= n; ++i)
read(a[i]);
lt[1] = 1, rt[1] = n, build(1);
for (R int i = 1; i <= n; ++i) {
int pos = query(1);
p[pos] = i, modify(1, pos, n, -i);
}
for (R int i = 1; i <= n; ++i)
printf("%d ", p[i]);
return 0;
}

最新文章

  1. 一篇对iOS音频比较完善的文章
  2. Android入门(十四)内容提供器-实现跨程序共享实例
  3. html5学习笔记6-- canvas
  4. wifidog 配置中文说明
  5. MVC乱码可能的原因
  6. web前端笔试题总结
  7. 1 weekend110的NN元数据管理机制 + NN工作机制 + DN工作原理
  8. Apache配置多个监听端口和不同的网站目录的简单方法(转)
  9. 记那一次C++开发电话面试
  10. prism silverlight
  11. JSP页面的静态包含和动态包含
  12. php之试触法----error--关键字的误用
  13. MySQL查询结果复制到新表(更新、插入)
  14. 利用1.1.1.1进行DNS网络加速,仅需2分钟让网络更快
  15. 常用linux命令备忘
  16. DBCP 连接池
  17. 10分钟了解JSON Web令牌(JWT)
  18. MySQL 错误集-汇总
  19. MongoDB下Map-Reduce使用简单翻译及示例
  20. 利用教育邮箱注册JetBrains产品(pycharm、idea等)的方法

热门文章

  1. 神经网络学习笔记一——Neural Network
  2. 【ASK】设置网卡启动遇到的事!
  3. BDD Cucumber 实战
  4. preventDefault 和 stopPropagation
  5. 转]@SuppressWarnings 详解
  6. Jmeter之循环控制器
  7. idea中配置tomcat详细
  8. 利用coverage工具进行Python代码覆盖率测试
  9. 十、Zabbix-自动关联模板
  10. [Python3] 003 变量类型概述 &amp; 数字类型详叙