首页 > 其他分享 >poj 2182

poj 2182

时间:2023-04-14 20:46:14浏览次数:47  
标签:lc int sum tr 2182 poj include define

Lost Cows

POJ - 2182

<iframe frameborder="0" height="2048px" id="frame-description" scrolling="no" src="https://vjudge.csgrandeur.cn/problem/description/1465306201?1681281450000" style="box-sizing: inherit; height: 1024px" width="100%"></iframe>

与这题一样Buy Tickets - POJ 2828 - Virtual Judge (csgrandeur.cn)

题意:有1~N N个数字,这N个数字的顺序是打乱的,从第二个数字开始给你它的前面有多少个数字比他小

思路:
输入的数字都要加一,然后我们从后往前遍历,在线段树中如果左子树的sum‘>sum,则进入左子树,否则,将sum-=sum',然后进入右子树,当到达叶子节点时更新答案,并将叶子结点的sum置为0。

为什么能这样写,可以自己模拟一下。

代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<algorithm>
#include<fstream>
#include<iostream>
#include<cstdio>
#include<deque>
#include<string>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
//#include<unordered_map>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 310000
#define N 210100
#define endl '\n'
#define exp 1e-8
#define lc p << 1
#define rc p << 1|1
#define lowbit(x) ((x)&-(x))
const double pi = acos(-1.0);
typedef long long LL;
typedef unsigned long long ULL;
inline LL read() {
	ULL x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch>'9') {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x * f;
}
struct tree
{
	int l, r,sum;
}tr[4*N];
map<int, bool>v;
int n, arr[N],ans[N];  //ans存答案
void pushup(int p)
{
	tr[p].sum = tr[lc].sum + tr[rc].sum;
}
void build(int p, int l, int r)
{
	tr[p].l = l, tr[p].r = r;
	if (tr[p].l == tr[p].r)
	{
		tr[p].sum = 1;
		return;
	}
	int m = l + r >> 1;
	build(lc, l, m);
	build(rc, m + 1, r);
	pushup(p);
}
void query(int p, int pos,int sum)
{
	if (tr[p].l == tr[p].r)
	{
		ans[pos] = tr[p].l;
		v[tr[p].l] = 1;
		tr[p].sum = 0;
		return;
	}
	if (tr[lc].sum >= sum)    //左子树大于sum走左边
		query(lc, pos, sum);
	else query(rc, pos, sum-tr[lc].sum); //否则sum减左子树的值,进入右子树
	pushup(p);
}
int main()
{
	cin >> n;
	build(1, 1, n);
	for (int i = 2; i <= n; i++)
	{
		cin >> arr[i];
	}
	for (int i = n; i >= 2; i--)   //从后往前遍历
	{
		query(1, i, arr[i] + 1);
	}
	for (int i = 1; i <= n; i++)  //是找第一个是谁
	{
		if (!v[i])
		{
			ans[1] = i;
			break;
		}
	}
	for (int i = 1; i <= n; i++)
	{
		printf("%d\n", ans[i]);
	}
	return 0;
}

标签:lc,int,sum,tr,2182,poj,include,define
From: https://www.cnblogs.com/wyh344866/p/17319899.html

相关文章

  • kuangbin专题一 简单搜索 抓住那头牛(POJ-3278)
    CatchThatCowTimeLimit:2000MS MemoryLimit:65536KTotalSubmissions:210291 Accepted:63838DescriptionFarmerJohnhasbeeninformedofthelocationofafugitivecowandwantstocatchherimmediately.HestartsatapointN(0≤N≤100,000)on......
  • kuangbin专题一 简单搜索 棋盘问题(POJ-1321)
    棋盘问题TimeLimit:1000MS MemoryLimit:10000KTotalSubmissions:125427 Accepted:56304Description在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘......
  • kuangbin专题一 简单搜索 地牢大师(POJ-2251)
    DungeonMasterTimeLimit:1000MS MemoryLimit:65536KTotalSubmissions:92499 Accepted:31990DescriptionYouaretrappedina3Ddungeonandneedtofindthequickestwayout!Thedungeoniscomposedofunitcubeswhichmayormaynotbefilledwith......
  • POJ 1780 Code (欧拉回路+非递归版dfs)
    题目地址:POJ1780还是求序列的欧拉回路。只不过这题有两坑。第一坑是用数字来当点的话,会MLE,因为每个数字可以连10条边,100w条边会MLE,即使用vector也会TLE。这题可以用边来记录,对于n为1时直接输出,然后后面的,比如12,23这两个点就用边权值为123来表示这两个点,这样就把点和边的范围......
  • HDU 1116 && POJ 1386 Play on Words(欧拉路径)
    按字母来建边,每个单词的首字母和尾字母加边。先判断是否连通,然后判断每个字母的入度和出度不能出现差的绝对值大于2,然后入度和出度差的绝对值为1的不能超过两个。就可以形成欧拉路径代码如下:#include<iostream>#include<string.h>#include<math.h>#include<queue>#include......
  • POJ 1753 Flip Game (高斯消元)
    题目地址:POJ1753第三次做这道题了。第一次是刚学搜索的时候做的,第二次是刚学状态压缩枚举的时候做的,这次是刚学高斯消元、、每次都做得很艰辛。。目测这题应该没了别的方法了吧。。。。。。这题除了高斯消元外还需要枚举变元,方法是状态压缩枚举,然后返回去迭代解方程。代码如下:#inc......
  • POJ 1830 开关问题 (高斯消元)
    题目地址:POJ1830高斯消元第一发。一个地方逻辑判断出现了失误,调了一下午啊。。。通过高斯消元来找矩阵的秩,然后2^(自由元的数量)就是答案。因为对于每个自由元,都有0和1两种状态可选。代码如下:#include<iostream>#include<string.h>#include<math.h>#include<queue>#includ......
  • POJ 2337 Catenyms (欧拉回路+并查集)
    题目地址:POJ2337这题跟POJ1386差不多,只不过这题多一个输出路径而已。按字母来建边,每个单词的首字母和尾字母加边。先判断是否连通,然后判断每个字母的入度和出度不能出现差的绝对值大于2,然后入度和出度差的绝对值为1的不能超过两个。就可以形成欧拉路径代码如下:#include<iostream......
  • POJ 1905 Expanding Rods (二分+计算几何+精度处理)
    题目地址:POJ1905用二分枚举h,然后判断弧长是否符合条件。重点还是在精度问题上,具体看代码吧。。#include<iostream>#include<string.h>#include<math.h>#include<queue>#include<algorithm>#include<stdlib.h>#include<map>#include<set>#include......
  • POJ 2299 Ultra-QuickSort(线段树+离散化)
    题目地址:POJ2299这题曾经用归并排序做过,线段树加上离散化也可以做。一般线段树的话会超时。这题的数字最大到10^10次方,显然太大,但是可以利用下标,下标总共只有50w。可以从数字大的开始向树上加点,然后统计下标比它小即在它左边的数的个数。因为每加一个数的时候,比该数大的数已经加完......