Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-D. Restore Permutation-构造+树状数组
Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-D. Restore Permutation-构造+树状数组

【Problem Description】
给你一个长度为\(n\)的数组,第\(i\)个元素\(s_i\)表示一个排列中第\(i\)个元素之前,并且小于\(p_i\)的元素的和。求出满足此条件的排列。
【Solution】
假设\(n=5\),\(s[]=\{0,0,3,7,3\}\)。从后往前看,最后一个值为\(3\),表示存在一个数\(x\),使得\(1+2+\dots+x=3\)。易知\(x=2\),所以\(p_5=x+1=3\)。然后第二个值为\(7\),表示存在一个数\(x\),使得\(1+2+\dots +x-3=7\)。减\(3\)是因为\(p_5=3\),不可能出现在\(p_4\)之前。所以可知\(x=4\),所以\(p_4=x+1=5\)。同理利用此方法可以求出此排列。
上述方法其实就是在找一个最大的\(x\),使得将所有满足\(1\le y\le x\),并且未出现过的\(y\)值相加使其等于\(s_i\),则\(p_i=x+1\)。可以想到用树状数组维护前缀和,用二分查找最大的满足条件的\(x\)。每求得一个数,就将此数清零即可。
但其实用树状数组中数组的特性,有更巧妙的方法。我们知道在树状数组中,对于数组\(tree[i]\),它所维护的区间为\([i-lowbit(i)+1,i]\),所以对于\(tree[2^i]\),它所维护的区间就为\([1,2^i]\)。所以就可以利用此特性加上树状数组的操作,维护一个类似倍增方法,并且支持在线修改操作。
例如求\(sum[1+2+\dots10]=tree[2^3]+tree[2^3+2^1]\)
【Code】
/*
* @Author: Simon
* @Date: 2019-08-26 18:14:20
* @Last Modified by: Simon
* @Last Modified time: 2019-08-26 20:12:53
*/
#include<bits/stdc++.h>
using namespace std;
typedef int Int;
#define int long long
#define INF 0x3f3f3f3f
#define maxn 200005
int a[maxn],tree[maxn],ans[maxn];
inline int lowbit(int x){
return x&(-x);
}
inline void update(int x,int val){
for(int i=x;i<maxn;i+=lowbit(i)){
tree[i]+=val;
}
}
inline int query(int x){
int ans=0;
for(int i=x;i>0;i-=lowbit(i)){
ans+=tree[i];
}
return ans;
}
int solve(int k,int n){
int num=0,sum=0;
for(int i=21;i>=0;i--){
if(num+(1<<i)<=n&&sum+tree[num+(1<<i)]<=k){//求一个最大num,使得sum[1+2+...+num]=k
num+=1<<i;
sum+=tree[num];
}
}
return num+1;
}
Int main(){
#ifndef ONLINE_JUDGE
//freopen("input.in","r",stdin);
//freopen("output.out","w",stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
int n;cin>>n;
for(int i=1;i<=n;i++){
update(i,i)/*初始所有值都存在*/;cin>>a[i];
}
for(int i=n;i>=1;i--){
ans[i]=solve(a[i],n);
update(ans[i],-ans[i]);//将ans[i]清零。
}
for(int i=1;i<=n;i++) cout<<ans[i]<<' ';
cout<<endl;
#ifndef ONLINE_JUDGE
system("pause");
#endif
return 0;
}
Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-D. Restore Permutation-构造+树状数组的更多相关文章
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-C. Magic Grid-构造
Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-C. Magic Grid-构造 [Problem Descripti ...
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-E. Let Them Slide-思维+数据结构
Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-E. Let Them Slide-思维+数据结构 [Problem ...
- CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组
题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum 题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有 ...
- CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组(转)
转载自:http://www.cnblogs.com/icode-girl/p/5744409.html 题目链接:CF #365 (Div. 2) D - Mishka and Interestin ...
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2) F. Bits And Pieces sosdp
F. Bits And Pieces 题面 You are given an array
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2) G. Polygons 数论
G. Polygons Description You are given two integers
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2) (1208F,1208G,1208H)
1208 F 大意: 给定序列$a$, 求$\text{$a_i$|$a_j$&$a_k$}(i<j<k)$的最大值 枚举$i$, 从高位到低位贪心, 那么问题就转化为给定$x$ ...
- RMQ+差分处理(Let Them Slide)Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)
题意:https://codeforc.es/contest/1208/problem/E 现有n行w列的墙,每行有一排连续方块,一排方块可以左右连续滑动,且每个方块都有一个价值,第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序列. 思路: 首 ...
随机推荐
- 基于Spring Boot架构的前后端完全分离项目API路径问题
最近的一个项目采用前后端完全分离的架构,前端组件:vue + vue-router + vuex + element-ui + axios,后端组件:Spring Boot + MyBatis.之所以 ...
- 【计算机视觉】黄金标准算法Gold Standard algorithm
前言 最近有关于3DMM的内容,博主也只是看了个大概,并没有深入了解算法的实现原理和过程.昨天实习生问关于黄金标准算法的推导,博主也就参考一些资料熟悉了这个算法的实现过程.不太了解使用这个算法的前因后 ...
- 【C/C++开发】C++11:左值引用VS右值引用
左值引用VS右值引用 左值引用对于一般的C++程序员再熟悉不过,但对于右值引用(C++0X新特性),就稍微有点不知所云 左值VS右值 在定义变量的时候,经常会用到左值和右值,比如:int a = 1; ...
- Redis Sentinel 高可用部署实践集群
一.Redis Sentinel 介绍 1.Sentinel 数据库环境搭建,从单机版到主备.再到多数据库集群,我们需要一个高可用的监控:比如Mysql中,我们可能会采用MHA来搭建我们 ...
- [转帖]Beyond compare4密钥
Beyond compare4密钥 https://blog.csdn.net/lemontree1945/article/details/92963423 学习一下 最近想破解水卡.... w4G- ...
- 以Unicode(UTF-16 LE)编码保存文本
1. 以二进制方式打开文件,写入BOM头 FILE* pFile = nullptr; _wfopen_s(&pFile, szLogFilePath, L"wb"); / ...
- AVR单片机教程——EasyElectronics Library v1.2手册
索引: bit.h delay.h pin.h wave.h pwm.h led.h rgbw.h button.h switch.h segment.h 主要更新: 添加了segment.h的文档: ...
- 5. Spark Streaming高级解析
5.1 DStreamGraph对象分析 在Spark Streaming中,DStreamGraph是一个非常重要的组件,主要用来: 1. 通过成员inputStreams持有Spark Strea ...
- MNIST机器学习入门(一)
一.简介 首先介绍MNIST 数据集.如图1-1 所示, MNIST 数据集主要由一些手写数字的图片和相应的标签组成,图片一共有10 类,分别对应从0-9 ,共10 个阿拉伯数字. 原始的MNIST ...
- windows 系统防火墙 添加端口号方法
目前在大部分公司内使用的台式机和部分服务器都采用了Windows操作系统,而我么都知道相当一部分病毒.恶意程序.黑客都是利用扫描端口号,利用开放的端口进行入侵,此时大型企业都会将服务器的系统防火墙打开 ...