模板写错了,研究了一个多小时,哭死
int kth(int root,int start,int end,int k) {//查询第k小值是多少
if(start==end)
return start;
int mid=(start+end)>>1,s1=tree[lson],s2=tree[rson];
if(k<=s1)
return kth(lson,start,mid,k);//向左子树搜索
else
return kth(rson,mid+1,end,k-s1);//向右子树搜索
}
倒数第二行k-s1不知道当初咋想的写成了k-mid,找了半天没发现错误,直到输出k发现有负数我才发现这个坑
回到题目
这题的英文是真恶心,读了几遍没读懂啥意思
题意:N头奶牛排队,它们的编号为1~n,知道每头牛前面有多少头比自己小,求每头牛的编号。
Sample Input
5 1 2 1 0
Sample Output
2 4 5 3 1
输入的第一行是N,第二行是乱序队列中第二头牛前面比他小的数目(不是0就是1,前面就一头),第一头省略了,肯定是0嘛,输出就是输出正序队列应有的编号
比如说样例输出后牛是这么排队的
1 3 5 4 2 右边为队首,左边为队尾 对着输入研究一下就能读懂题了
读懂题之后,我们发现,看最后一头牛的话,0就意味着前面有0头牛比他小,那他不就是第一小的么,就像你考试前面有0个人成绩比你高,那你就是第一了。那么,看最后一头牛,设输入为t[i],他就是第t[i]+1小。然后我们把牛出队就行了,循环看下一个队尾牛,直到队空,算法结束。
N<=8e4,嘿,不用动态开点了,很简单的题(如果模板没写错题目能读懂的话,这题我一开始愣是没读懂)
#include<cstdio>//权值线段树https://www.cnblogs.com/fusiwei/p/11301700.html
#include<iostream>
#define lson root<<1
#define rson root<<1|1
using namespace std;
const int N=1e6+10;
int a[N];//!!!初始数组,表示一开始元素的个数,建树要用!
int tree[N<<1];
void build(int root,int start,int end) {//通常在主函数中这么使用:build(1,1,N);
int mid=(start+end)>>1;
if(start==end) {
tree[root]=a[start];//a[start]表示数start有多少个
return;
}
build(lson,start,mid);
build(rson,mid+1,end);
tree[root]=tree[lson]+tree[rson];
}
void update(int root,int start,int end,int k,int cnt) { //表示数k的个数多cnt个
int mid=(start+end)>>1;
if(start==end) {
tree[root]+=cnt;
return;
}
if(k<=mid)
update(lson,start,mid,k,cnt);
else
update(rson,mid+1,end,k,cnt);
tree[root]=tree[lson]+tree[rson];
}
int kth(int root,int start,int end,int k) {//查询第k小值是多少
if(start==end)
return start;
int mid=(start+end)>>1,s1=tree[lson],s2=tree[rson];
if(k<=s1)
return kth(lson,start,mid,k);//向左子树搜索
else
return kth(rson,mid+1,end,k-s1);//向右子树搜索
}
int main() {
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++) { //1~n计数+1
a[i]=1;
}
build(1,1,n);
int t[8010]= {},ans[8010]= {};
for(int i=2; i<=n; i++) { //t[i]前面有几头牛比他小,那么这头牛就是第t[i]+1小
scanf("%d",t+i);
}
for(int i=n; i>=1; i--) { //队列中最后一头牛i是第t[i]+1小,找到这头牛,然后出队,循环 ;
ans[i]=kth(1,1,n,t[i]+1);
update(1,1,n,ans[i],-1);
}
for(int i=1; i<=n; i++) {
printf("%d\n",ans[i]);
}
return 0;
}