[CF1208D] Restore Permutation
题意:有一个长为\(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;
}
[CF1208D] Restore Permutation的更多相关文章
- D. Restore Permutation(权值线段树)
D. Restore Permutation time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- D. Restore Permutation
D. Restore Permutation 就是给一个n个数的全排,然后bi记录比ai小且在排在ai前面的数的和,求ai 树状数组维护,二分 #include<bits/stdc++.h> ...
- [Codeforces 1208D]Restore Permutation (树状数组)
[Codeforces 1208D]Restore Permutation (树状数组) 题面 有一个长度为n的排列a.对于每个元素i,\(s_i\)表示\(\sum_{j=1,a_j<a_i} ...
- D. Restore Permutation 树状数组+二分
D. Restore Permutation 题意:给定n个数a[i],a[ i ]表示在[b[1],b[i-1]]这些数中比 b[i]小的数的和,要你构造这样的b[i]序列 题解:利用树状数组 求比 ...
- 线段树维护最后一个0的位置(Restore Permutation)Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)
题意:https://codeforc.es/contest/1208/problem/D 给你长度为n的序列,s[i]的值为p[1]到p[i-1]中比p[i]小的数的和,让你求出p序列. 思路: 首 ...
- 1208D Restore Permutation
题目大意 给你一个序列s 让你求一个1~n的序列 使得对于第i个位置它前面所有小于p[i]的数的和恰好为s[i] 分析 我们可以从后往前确定每一位 每次一二分找到恰好等于s[i]的数 但是我们发现这样 ...
- cf1208 D Restore Permutation (二分+树状数组)
题意 让你构造一个长度为n的序列,记为p1……pn,(这个序列是1~n的全排列的一种) 给你n个数,记为s1……sn,si的值为p1……pi-1中小于pi的数的和. 思路 显然,应该倒着来,也就是从p ...
- 一句话CF
目录 \(\bf {Round \ \#500 \ (Div. \ 1)}\) \(\bf {Round \ \#589 \ (Div. \ 2)}\) \(\bf {Avito \ Cool \ C ...
- Manthan Codefest 19 题解
这套题还是有点质量的吧 -- 题目链接 A. XORinacci 傻叉签到题,因为异或的性质所以这个序列的循环节长度只有 \(3\) -- 查看代码 B. Uniqueness 因为序列长度乃至数的种 ...
随机推荐
- python - del 方法
转自:http://blog.csdn.net/love1code/article/details/47276683 python中的del用法比较特殊,新手学习往往产生误解,弄清del的用法,可以帮 ...
- Jmeter之HTTP常用配置元件(默认、头信息和cookies)
在进行HTTP接口的测试时,会用到部分常用的配置元件,现在简单的说明: 一.HTTP请求默认值 在测试同一个项目的HTTP请求接口时,会存在部分相同的信息,可以将这些相同的信息提取出来,使用HTTP请 ...
- C#与Java覆盖问题
C#继承类中如含有相同的方法,避免冲突使用new关键字.在不同对象中分别对应该方法.若使用override关键字则,基类中的方法被覆盖. 如需调用非覆盖的则使用base关键字. Java中的继承类方法 ...
- 使用事件CreateEvent注意事项 多进程同步的方法
https://www.cnblogs.com/aakuang/p/3514658.html 使用事件CreateEvent注意事项 HANDLECreateEvent( LPSECURITY_A ...
- Java课堂疑问解答与思考4
一. 请运行以下示例代码StringPool.java,查看其输出结果.如何解释这样的输出结果?从中你能总结出什么? 答:定义的三个字符串如果相等,系统自动创建一个,并调用这个,对于由new创建的字符 ...
- vim加脚本注释和文本加密
vim /etc/vimrc 一.李导版本 autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()" fun ...
- wiki团队协作软件Confluence
一.准备环境 准备环境 lamp(Linux.apache.mysql.php)框架 centos7 java jdk1.8.0_111 Distrib 5.5.52-MariaDB confluen ...
- Canvas入门06-线段与像素边界
我们知道,使用以下2个API可以绘制一条线段: moveTo(x, y) 向当前路径中增加一条子路径,该子路径只包含一个点,此为线段的起始点 lineTo(x, y) 将线段的下一个点加入子路径中 c ...
- 第九周课程总结&实验报告7
实验任务详情: 完成火车站售票程序的模拟.要求:(1)总票数1000张:(2)10个窗口同时开始卖票:(3)卖票过程延时1秒钟:(4)不能出现一票多卖或卖出负数号票的情况. 实验代码: package ...
- 为什么 Java 线程没有 Running 状态?
Java虚拟机层面所暴露给我们的状态,与操作系统底层的线程状态是两个不同层面的事.具体而言,这里说的 Java 线程状态均来自于 Thread 类下的 State 这一内部枚举类中所定义的状态: 什么 ...