开了O2优化AC,不开WA了两个??
查看原帖
开了O2优化AC,不开WA了两个??
343801
johnathan楼主2020/5/10 21:51

最后两个数据点WA了,请大佬帮忙看一下

#include <bits/stdc++.h>
using namespace std;
#define N 200000
long long int a[N], cpy[N];
int lsh[N];
int cnt;      /*节点编号*/
int root[N];  /*记录第i个“线段树”根节点编号*/
int ma;       /*数据离散化之后的最大值*/
struct node{
	int ls, rs, val;
	/*该节点左、右儿子节点编号;权值*/
}tree[32 * N];
void buildtree(int i, int l, int r)
/*当前第i个节点;线段左端点;线段右端点*/
{
	cnt++;
	if (l == r)
		return;
	tree[i].ls = 2 * i;tree[i].rs = 2 * i + 1;
	int mid = (l + r) / 2;
	buildtree(2 * i, l, mid);
	buildtree(2 * i + 1, mid + 1, r);
}
void change(int l, int r, int now, int past, int k);
void add(int i, int k)
/*当前“线段树”的编号;将插入的数*/
{
	root[i] = ++cnt;
	/*cnt现在是新“线段树”的根节点节点编号*/
	tree[cnt].val = tree[root[i - 1]].val + 1;
	/*新建节点完毕,开始向下延伸*/
	change(1, ma, cnt, root[i - 1], k);
}
void change(int l, int r, int now, int past, int k)
/*当前区间[l r];新“线段树”的当前节点编号now;
上一棵“线段树”的当前节点编号past;将插入的数*/
{
	/*如果已经遍历到叶子结点*/
	if (!tree[past].ls && !tree[past].rs)
		return;
	int mid = (l + r) / 2;
	/*如果要插入的数即将影响该节点的右儿子区间*/
	if (k > mid)
	{		
		/*连上上一棵树的左儿子作为新树的左儿子*/
		tree[now].ls = tree[past].ls;
		/*右儿子需要开新点*/
		tree[now].rs = ++cnt;
		/*更新右儿子的权值*/
		tree[cnt].val = tree[tree[past].rs].val + 1;
		change(mid + 1, r, cnt, tree[past].rs, k);
	}
	else
	{
		/*左边一样的道理*/
		tree[now].rs = tree[past].rs;
		tree[now].ls = ++cnt;
		tree[cnt].val = tree[tree[past].ls].val + 1;
		change(l, mid, cnt, tree[past].ls, k);
	}
}
int kth(int a, int b, int l, int r, int k)
/*区间首尾对应的“线段树”根节点a, b;当前区间[l r];查询第k小的数*/
{
	if (l == r)
		return l;
	int lm = tree[tree[b].ls].val - tree[tree[a].ls].val;
	/*lm是区间[a b]的权值二叉树根节点左儿子的值*/
	int mid = (l + r) / 2;
	if (k <= lm)
		return kth(tree[a].ls, tree[b].ls, l, mid, k);
	return kth(tree[a].rs, tree[b].rs, mid + 1, r, k - lm);
}
int main()
{
	int n, m, i;
	scanf("%d%d", &n, &m);
	for (i = 1;i <= n;i++)
	{
		scanf("%lld", &a[i]);
		cpy[i] = a[i];
	}
	sort(a + 1, a + 1 + n);
	ma = unique(a + 1, a + 1 + n) - (a + 1);
	for (i = 1;i <= n;i++)
		lsh[i] = lower_bound(a + 1, a + 1 + ma, cpy[i]) - a;
	/*建空树*/
	buildtree(1, 1, ma);
	root[0] = 1;
	for (i = 1;i <= n;i++)
		add(i, lsh[i]);
	while (m--)
	{
		int l, r, k;
		scanf("%d%d%d", &l, &r, &k);
		int ans = kth(root[l - 1], root[r], 1, ma, k);
		printf("%lld\n", a[ans]);
	}
	return 0;
}
2020/5/10 21:51
加载中...