名校联赛第三天A层 问题 B: Number

问题 B: Number

时间限制: 1 Sec  内存限制: 256 MB

题目描述

一个排列,求出了 a 数组,其中 ai 表示第 i 个数左边有多少个数比它小

计算出原来的排列

输入

第一行输入 n 接下来 n - 1 个整数 ai,下标从 2 开始

输出

输出 n 个整数表示原排列

样例输入

5
1
2
1
0

样例输出

2
4
5
3
1

提示

对于 20% 的数据满足:1 ≤ n ≤ 10

对于 50% 的数据满足:1 ≤ n ≤ 1000

对于 100% 的数据满足,1 ≤ n ≤ 100000

保证解存在

  这道题说来蛮可惜的,当时正解的原理都已经想明白了,然而,然而居然因为第一题太烦心,没仔细去向正解,只想着拿暴力分,呵呵了。

  不知道大家想没想出来,数列中最小的数是最右方的0,次小数就是将0右方的所有数-1后 最右方的0,以此类推……所以就很好想了,题目数据可以让我们去确定n logn,因为在枚举每一位数时已经有n的复杂度了,因此我们需要一个为log n复杂度的东西求出来区间最小,线段树就好了,当然,平衡树也可以,只不过是熟悉线段树才打的线段树罢了。

  1 #include<iostream>
  2 #include<cstdlib>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<map>
  7 #include<queue>
  8 #include<string>
  9 #include<cmath>
 10 using namespace std;
 11 int n,m,a[100005];
 12 struct no{
 13     int left,right;
 14     int mid;
 15     int mn,lazy;
 16 }node[500005];
 17 void build(int left,int right,int x){
 18     node[x].left=left;
 19     node[x].right=right;
 20     if(left==right)
 21     {
 22         node[x].mn=a[left];
 23         return;
 24     }
 25     int mid=(left+right)/2;
 26     node[x].mid=mid;
 27     build(left,mid,2*x);
 28     build(mid+1,right,2*x+1);
 29     node[x].mn=min(node[x*2].mn,node[2*x+1].mn);
 30 }
 31 void pushdown(int x){
 32     if(node[x].lazy)
 33     {
 34         node[2*x].lazy+=node[x].lazy;
 35         node[2*x+1].lazy+=node[x].lazy;
 36         node[x*2].mn+=node[x].lazy;
 37         node[2*x+1].mn+=node[x].lazy;
 38         node[x].lazy=0;
 39     }
 40 }
 41 void add(int left,int right,int x,int z){
 42     if(node[x].left==left&&node[x].right==right)
 43     {
 44         node[x].mn+=z;
 45         node[x].lazy+=z;
 46         return;
 47     }
 48     pushdown(x);
 49     int mid=node[x].mid;
 50     if(right<=mid)
 51         add(left,right,2*x,z);
 52     else if(mid<left)
 53         add(left,right,2*x+1,z);
 54     else
 55     {
 56         add(left,mid,2*x,z);
 57         add(mid+1,right,2*x+1,z);
 58     }
 59     node[x].mn=min(node[x*2].mn,node[x*2+1].mn);
 60 }
 61 void change(int left,int right,int x,int z){
 62     if(node[x].left==node[x].right)
 63     {
 64         node[x].mn=z;
 65         return;
 66     }
 67     pushdown(x);
 68     int mid=node[x].mid;
 69     if(left<=mid)
 70         change(left,right,x*2,z);
 71     else
 72         change(left,right,2*x+1,z);
 73     node[x].mn=min(node[2*x].mn,node[2*x+1].mn);
 74     return;
 75 }
 76 int get(int x){
 77     if(node[x].left==node[x].right)
 78     {
 79         return node[x].left;
 80     }
 81     pushdown(x);
 82     if(node[2*x+1].mn==0)
 83         return get(2*x+1);
 84     else
 85         return get(2*x);
 86 }
 87 int b[100005];
 88 int main(){
 89     scanf("%d",&n);
 90     for(int i=2;i<=n;i++)
 91         scanf("%d",&a[i]);
 92     build(1,n,1);
 93     for(int i=1;i<=n;i++)
 94     {
 95         int x=get(1);
 96         b[x]=i;
 97         change(x,x,1,0x7fffffff);
 98         if(x<n)
 99             add(x+1,n,1,-1);
100     }
101     for(int i=1;i<=n;i++)
102         printf("%d\n",b[i]);
103     //while(1);
104     return 0;
105 }

时间: 2024-08-08 12:53:09

名校联赛第三天A层 问题 B: Number的相关文章

名校联赛第三天A层 Evensgn 的债务题解

问题 A: Evensgn 的债务 时间限制: 1 Sec  内存限制: 128 MB 题目描述 Evensgn 有一群好朋友,他们经常互相借钱.假如说有三个好朋友 A,B,C. A 欠 B 20 元,B 欠 C 20 元,总债务规模为 20+20=40 元.Evensgn 是个追求简约 的人,他觉得这样的债务太繁杂了.他认为,上面的债务可以完全等价为 A 欠 C 20 元,B 既不欠别人,别人也不欠他.这样总债务规模就压缩到了 20 元. 现在给定 n 个人和 m 条债务关系.Evensgn 

名校联赛第三天A层 问题 C: 与非题解

问题 C: 与非 时间限制: 2 Sec  内存限制: 256 MB 题目描述 作为一名新世纪共产主义的接班人,你认识到了资本主义的软弱性与妥协性,决定全面根除资本主义,跑步迈入共产主义.但是当你即将跨入共产主义大门的时候,遇到了万恶的资本家留下的与非电路封印,经过千辛万苦的研究,你终于把复杂的破解转变成了以下问题: 初始时你有一个空序列,之后有N个操作. 操作分为一下两种: 1 x:在序列末尾插入一个元素x(x=0或1). 2 L R:定义nand[L,R]为序列第L个元素到第R个元素的与非和

名校联赛DAY.2A层第三题book(书)题解

书 时间限制: 1 Sec  内存限制: 512 MB 题目描述 书 book.in/.out Hazel有n本书,编号1为n到 ,叠成一堆.当她每次抽出一本书的时候,上方的书会因重力而下落,这本被取出的书则会被放置在书堆顶. 每次有pi的概率抽取编号为i的书.她每次抽书所消耗的体力与这本书在这堆中是第几本成正比.具体地,抽取堆顶的书所耗费体力值为1 ,抽取第二本耗费体力值为2 ,以此类推. 现在 想知道,在很久很久以后(可以认为几乎是无穷的),她每次抽书所耗费的体力的期望值是多少. 最终的答案

原生js实现三个div层动态交换位置

html代码部分 <!--触发变换按钮--> <input type="button" onclick="startMove()" value="点击"/> <!--主体部分--> <div class="localbox"> <div id="b1" class="block1"></div> <div id

Python黑帽编程3.0 第三章 网络接口层攻击基础知识

3.0 第三章 网络接口层攻击基础知识 首先还是要提醒各位同学,在学习本章之前,请认真的学习TCP/IP体系结构的相关知识,本系列教程在这方面只会浅尝辄止. 本节简单概述下OSI七层模型和TCP/IP四层模型之间的对应关系,最后是本章教程需要的几个核心Python模块. 3.0.1 TCP/IP分层模型 国际标准化组织(ISO)在1978年提出了"开放系统互联参考模型",即著名的OSI/RM模型(Open System Interconnection/Reference Model).

【cocos2d-x学习笔记】ZOder、tag、场景切换、精灵的各种创建方式、三个特殊层、坐标体系

ZOder: 1.是描述渲染顺序的值,每个CCNode都有ZOder,默认是0. 2.ZOder越大则越后面绘制.如果ZOder值相同,那么看arrival(全局变量每次加一)顺序,先加入的节点先绘制,ZOder只在相同父节点的节点直接进行比较 tag:是一个节点的身份证,方便通过getChildByTag来获取节点对象,它的意义在于减少成员变量 TAG只在相同父节点的节点之间有效 TAG在相同父节点的儿子之间不能相同,相同情况cocos不报错,getChildByTag可能会获取到不是你想要的

名校联赛DAY.2A层第二题SO(就)题解

问题 B: 就 时间限制: 1 Sec  内存限制: 512 MB 题目描述 就so.in/.out [背景描述] 一排 N 个数, 第 i 个数是 Ai , 你要找出 K 个不相邻的数, 使得他们的和最大. 请求出这个最大和. [输入格式] 第一行两个整数 N 和 K. 接下来一行 N 个整数, 第 i 个整数表示 Ai . [输出格式] 一行一个整数表示最大和, 请注意答案可能会超过 int 范围 [样例输入] 3 2 4 5 3 [样例输出] 7 [数据范围] 对于 20% 的数据, N,

名校联赛DAY.2A层第一题passward题解

问题 A: Passward 时间限制: 1 Sec  内存限制: 512 MB 题目描述 你来到了一个庙前,庙牌上有一个仅包含小写字母的字符串 s. 传说打开庙门的密码是这个字符串的一个子串 t,并且 t 既是 s 的前缀又是 s的后缀并且还在 s 的中间位置出现过一次. 如果存在这样的串,请你输出这个串,如有多个满足条件的串,输出最长的那一个. 如果不存在这样的串,输出"Just a legend"(去掉引号). 输入格式: 仅一行,字符串 s. 输出格式: 如题所述 样例输入 f

[CAMCOCO][C#]我的系统架构.服务器端.(三)----Model层

我估计一片帖子写不完这个,慢慢来吧... 先上个图,按照图来说明应该容易说清楚一些. 在Model Core核心代码中,老胡创建了一个类 CAMCOCO.Model.Core,要求今后在Model Logic中编写的实体类都必须从这里继承. Core里提供了两种基类,一个是Entity的基类,一个是Filter基类. 先给出实体类的继承结构:代码有点多,点开再看^v^ 1 namespace CAMCOCO.Model.Core.Entity 2 { 3 using System; 4 5 #r