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序列. 思路: 首 ...
随机推荐
- helm安使用
参照:https://juejin.im/post/5b6590afe51d4519962f02b1
- mongodb 分组求最大值
先上代码 db.getCollection("playback").aggregate([ {$match:{"game_record_id":{$in:[68 ...
- 三层交换,单臂路由,vtp
- Windows下的免安装版MySQL配置
原文地址:https://blog.csdn.net/qq_40277973/article/details/81517479 近日在新的电脑上安装MySQL遇到一些小问题,在此做分享,也作为日后备用 ...
- jquery监听回车
jquery监听回车 <pre> $("#loginusername, #loginpassword, #code").keydown(function() { if( ...
- GetComponentsInChildren<Transform>(true)
GetComponentsInChildren<Transform>(true);//游戏对象下的子物体激活的没激活的都会被拿到,包括游戏对象本身GetComponentsInChildr ...
- 机器学习中什么是端到端的学习(end-to-end learning)?
相对于深度学习,传统机器学习的流程往往由多个独立的模块组成,比如在一个典型的自然语言处理(Natural Language Processing)问题中,包括分词.词性标注.句法分析.语义分析等多个独 ...
- log4j重复打印的解决方法
log4j的logger(旧版本称logger)是层次结构的,子logger会继承父logger的属性,appender也是可继承的属性,这常常 容易导致配置错误而引起的log4j输出重复的log信息 ...
- JVM性能调优的6大步骤,及关键调优参数详解
JVM性能调优方法和步骤1.监控GC的状态2.生成堆的dump文件3.分析dump文件4.分析结果,判断是否需要优化5.调整GC类型和内存分配6.不断分析和调整JVM调优参数参考 对JVM内存的系统级 ...
- 通过werkzeug了解wsgi
Django有wsgi当做socket,而flask自身是没有wsgi的,他是通过werkzeug来实现的. 看源码 下面看下源码是如何实现的: #这是我们写的flask代码from flask im ...