1 条题解
-
0
题意分析
- 核心问题:
- 给定一个静态数组(狗的漂亮值),处理多个区间查询,每次查询区间中第小的值(第漂亮的狗)。
- 限制条件:
- 所有查询区间互不包含,但可以交叉。
- 漂亮值较低的狗更漂亮(即求区间第小值)。
解题思路
- 数据结构选择:
- 使用主席树维护区间的权值线段树,支持高效查询区间第小值。
- 由于区间互不包含,无需处理动态修改,适合离线构建。
- 查询处理:
- 对每个查询,利用主席树的差分性质()在时间内得到第小值。
实现步骤
- 离散化处理:
- 将狗的漂亮值离散化为排名,减少权值线段树的空间开销。
- 构建主席树:
- 从左到右依次插入每个元素,构建可持久化版本。
- 处理查询:
- 对每个查询,在主席树上二分查找第小的离散化值,再映射回原始漂亮值。
- 输出结果:
- 对每个查询直接返回计算得到的漂亮值。
代码实现
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #include<queue> #define LL long long #define lim 1000000000 #define inf 2147483640 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); using namespace std; const int maxn=100010; int n,m,sz,rt[maxn]; struct node { int son[2],s; int& operator [] (int x) {return son[x];} }tr[maxn*40]; void build(int &u,int v,int l,int r,int val) { u=++sz; if (l==r) {tr[u].s=tr[v].s+1;return;} int mid=(l+r)>>1; if (val<=mid) build(tr[u][0],tr[v][0],l,mid,val),tr[u][1]=tr[v][1]; else build(tr[u][1],tr[v][1],mid+1,r,val),tr[u][0]=tr[v][0]; tr[u].s=tr[tr[u][0]].s+tr[tr[u][1]].s; } int query(int u,int v,int l,int r,int k) { if (l==r) return l; int mid=(l+r)>>1,c=tr[tr[v][0]].s-tr[tr[u][0]].s; if (c>=k) return query(tr[u][0],tr[v][0],l,mid,k); else return query(tr[u][1],tr[v][1],mid+1,r,k-c); } int main() { scanf("%d%d",&n,&m); for (int x,i=1;i<=n;i++) { scanf("%d",&x); build(rt[i],rt[i-1],-lim,lim,x); } for (int x,y,k,i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&k); printf("%d\n",query(rt[x-1],rt[y],-lim,lim,k)); } return 0; }
- 核心问题:
- 1
信息
- ID
- 1761
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 5
- 已通过
- 1
- 上传者