此链接存在问题:http://codeforces.com/blog/entry/9204
我无法解决,所以我决定阅读answer。 这是解决方案:
#include <cstdio>
#include <map>
#include <vector>
#include <cstring>
using namespace std;
#define sz size()
#define pb push_back
#define rep(i,n) for(int i=0;i<n;i++)
#define fd(i,a,b) for(int i=a; i>=b; i--)
#define N 111111
struct node
{
int count;
node *left, *right;
node(int count, node *left, node *right):
count(count), left(left), right(right) {}
node* insert(int l, int r, int w);
};
node *null = new node(0, NULL, NULL); //see line 135
node * node::insert(int l, int r, int w)
{
if(l <= w && w < r)
{
// With in the range, we need a new node
if(l+1 == r)
{
return new node(this->count+1, null, null);
}
int m = (l+r)>>1;
return new node(this->count+1, this->left->insert(l, m, w), this->right->insert(m, r, w));
}
// Out of range, we can use previous tree node.
return this;
}
int query(node *a, node *b, int l, int r, int k)
{
if(l+1 == r)
{
return l;
}
int m = (l+r)>>1;
int count = a->left->count - b->left->count;
if(count >= k)
return query(a->left, b->left, l, m, k);
return query(a->right, b->right, m, r, k-count);
}
int a[N], RM[N];
node *root[N];
int main()
{
int n, m;
scanf("%d%d", &n, &m);
map <int, int> M;
rep(i, n)
{
scanf("%d", &a[i]);
M[a[i]];
}
int maxi = 0;
for(map <int, int> :: iterator it = M.begin(); it != M.end(); it++)
{
M[it->first] = maxi;
RM[maxi] = it->first;
maxi++;
}
null->left = null->right = null;
rep(i, n)
{
// Build a tree for each prefix using segment tree of previous prefix
root[i] = (i == 0 ? null : root[i-1])->insert( 0, maxi, M[a[i]] );
}
while(m--)
{
int u, v, k;
scanf("%d%d%d", &u, &v, &k);
u--; v--;
int ans = query(root[v], (u==0?null:root[u-1]), 0, maxi, k);
printf("%d\n", RM[ans]);
}
}
我在这段代码中无法理解的一些事情:
M[a[i]];
在主函数的第一个循环中意味着什么?!count
在节点结构中做了什么?!我知道它使用了分段树,但很难理解解决方案。
如果有人能帮助我,我会很高兴:) 提前谢谢
答案 0 :(得分:4)
M[a[i]]
只是尝试访问地图的该元素。这会导致使用默认值创建元素。它这样做,以便第二个循环将看到地图的所有元素。
我不完全确定,但我认为count
是树深度的衡量标准。每次创建一个新节点时,它都会从插入新节点的节点递增它。