第十二次新生排位赛
第一题
494. Study sister's barbarian
时间限制 2000 ms 内存限制 65536 KB
题目描述
Study sister plays the game coc everyday. When she wants to attack another clan, Study brothers will donate a lot of barbarian to help her.
We assume that there are n Study brothers and each of them send one barbarian to help Study sister. The barbarians had different hitpoints, and they had to stand in one line when they get out of the clan.
Some Study brothers wants to impress Study sister, so they wants their own barbarian become the ai-th barbarian that get out of the clan. We know that Study brothers donate their barbarian in turn, so the order they choose when they donate the army may not be the final order. Now given the donating behavior in order, Study sister wants to know the final sequence of barbarian by their hitpoints.
输入格式
There are several test case. Each test case begin with a sigal integer n(1<=n<=200000), means the number of Study brothers. Next n line, each line contains two integer a, b, means the i-th Study brother wants his barbarian become the a-th army that get out of the clan, and its hitpoints is b. 0<=a<i, 0<=b<100000.
There are break line between each test case.
输出格式
For each case, print one line, the final sequence of barbarian by their hitpoints.
输入样例
4
0 77
1 51
1 33
2 69
输出样例
77 33 69 51
hint:
the process are:
a barbarian of 77 hitpoints wants to become the 0-th, now the sequence becomes: 77
a barbarian of 51 hitpoints wants to become the 1-th, now the sequence becomes: 77 51
a barbarian of 33 hitpoints wants to become the 1-th, now the sequence becomes: 77 33 51
a barbarian of 69 hitpoints wants to become the 2-th, now the sequence becomes: 77 33 69 51
> 这题是poj原题2828,可以用树状数组加二分来做,也可以用线段树来做,由于线段树已带二分性质,所以比线段树快了一半的时间 题目主要的一个思想是逆序思考。假设共有n个数,最后一个放进去的肯定放在他所指定i-th的位置,倒数第二个放在剩下的空格的第i-th,所以题目转变成了计算当前第i-th空格实际位置在哪里。可以预处理n个位置原来都是0, 放一个就是该位置变成1,某一个位置pos(包括它自己)前面的空格的个数就是pos - sum(pos);当然也可以预处理n个位置原来都是1, 放一个就是该位置-1变成0,某一个位置pos(包括它自己)前面的空格的个数就是sum(pos);strong text
----------
```
c++
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>
typedef unsigned long long ull;
using namespace std;
int ans[200005];
int a[200005];
int b[200005];
int c[200005];
int n;
void update(int pos, int w)
{
while(pos<=n)
{
c[pos] += w;
pos += pos&-pos;
}
}
int sum(int pos)
{
int ans=0;
while(pos)
{
ans+=c[pos];
pos -= pos&-pos;
}
return ans;
}
int get(int pos)
{
int head=1;
int last=n;
int mid=(head+last)/2;
int t=mid-sum(mid);
while (t!=pos)
{
if (t>pos)
{
last = mid;
}
else head = mid+1;
mid=(head+last)/2;
t=mid-sum(mid);
}
return mid;
}
int main()
{
while (~scanf("%d", &n))
{
int a1, b1;
for (int i=1; i<=n; i++)
{
scanf("%d %d", &a1, &b1);
a[i] = a1+1;
b[i] = b1;
c[i] = 0;
ans[i] = -1;
}
for (int i=n; i>0; i--)
{
int t = get(a[i]);
while (ans[t]!=-1) t--;
ans[t] = b[i];
update(t, 1);
}
for (int i=1; i<=n; i++)
{
printf("%d", ans[i]);
if (i<n) printf(" ");
}
printf("\n");
}
return 0;
}
```
第一题
494. Study sister's barbarian
时间限制 2000 ms 内存限制 65536 KB
题目描述
Study sister plays the game coc everyday. When she wants to attack another clan, Study brothers will donate a lot of barbarian to help her.
We assume that there are n Study brothers and each of them send one barbarian to help Study sister. The barbarians had different hitpoints, and they had to stand in one line when they get out of the clan.
Some Study brothers wants to impress Study sister, so they wants their own barbarian become the ai-th barbarian that get out of the clan. We know that Study brothers donate their barbarian in turn, so the order they choose when they donate the army may not be the final order. Now given the donating behavior in order, Study sister wants to know the final sequence of barbarian by their hitpoints.
输入格式
There are several test case. Each test case begin with a sigal integer n(1<=n<=200000), means the number of Study brothers. Next n line, each line contains two integer a, b, means the i-th Study brother wants his barbarian become the a-th army that get out of the clan, and its hitpoints is b. 0<=a<i, 0<=b<100000.
There are break line between each test case.
输出格式
For each case, print one line, the final sequence of barbarian by their hitpoints.
输入样例
4
0 77
1 51
1 33
2 69
输出样例
77 33 69 51
hint:
the process are:
a barbarian of 77 hitpoints wants to become the 0-th, now the sequence becomes: 77
a barbarian of 51 hitpoints wants to become the 1-th, now the sequence becomes: 77 51
a barbarian of 33 hitpoints wants to become the 1-th, now the sequence becomes: 77 33 51
a barbarian of 69 hitpoints wants to become the 2-th, now the sequence becomes: 77 33 69 51
> 这题是poj原题2828,可以用树状数组加二分来做,也可以用线段树来做,由于线段树已带二分性质,所以比线段树快了一半的时间 题目主要的一个思想是逆序思考。假设共有n个数,最后一个放进去的肯定放在他所指定i-th的位置,倒数第二个放在剩下的空格的第i-th,所以题目转变成了计算当前第i-th空格实际位置在哪里。可以预处理n个位置原来都是0, 放一个就是该位置变成1,某一个位置pos(包括它自己)前面的空格的个数就是pos - sum(pos);当然也可以预处理n个位置原来都是1, 放一个就是该位置-1变成0,某一个位置pos(包括它自己)前面的空格的个数就是sum(pos);strong text
----------
```
c++
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>
typedef unsigned long long ull;
using namespace std;
int ans[200005];
int a[200005];
int b[200005];
int c[200005];
int n;
void update(int pos, int w)
{
while(pos<=n)
{
c[pos] += w;
pos += pos&-pos;
}
}
int sum(int pos)
{
int ans=0;
while(pos)
{
ans+=c[pos];
pos -= pos&-pos;
}
return ans;
}
int get(int pos)
{
int head=1;
int last=n;
int mid=(head+last)/2;
int t=mid-sum(mid);
while (t!=pos)
{
if (t>pos)
{
last = mid;
}
else head = mid+1;
mid=(head+last)/2;
t=mid-sum(mid);
}
return mid;
}
int main()
{
while (~scanf("%d", &n))
{
int a1, b1;
for (int i=1; i<=n; i++)
{
scanf("%d %d", &a1, &b1);
a[i] = a1+1;
b[i] = b1;
c[i] = 0;
ans[i] = -1;
}
for (int i=n; i>0; i--)
{
int t = get(a[i]);
while (ans[t]!=-1) t--;
ans[t] = b[i];
update(t, 1);
}
for (int i=1; i<=n; i++)
{
printf("%d", ans[i]);
if (i<n) printf(" ");
}
printf("\n");
}
return 0;
}
```