标签:oal iostream for ring 线段树 cst efi scanf date
#include<stdio.h> #include<iostream> #include<algorithm> #include<cstring> using namespace std; const int maxn = 1e5 + 10; int n, m; int cnt; struct node{ int L, R;//分别指向左右子树 int sum;//该节点所管辖区间范围内数的个数 node(){ sum = 0; } }Tree[maxn * 20]; struct value{ int x;//值的大小 int id;//离散之前在原数组中的位置 }Value[maxn]; bool cmp(value v1, value v2) { return v1.x < v2.x; } int root[maxn];//多颗线段树的根节点 int Rank[maxn];//原数组离散之后的数组 void init() { cnt = 1; root[0] = 0; Tree[0].L = Tree[0].R = Tree[0].sum = 0; } void update(int num, int &rt, int l, int r) { Tree[cnt++] = Tree[rt]; rt = cnt - 1; Tree[rt].sum++;if(l == r) return; int mid = l + ((r-l)>>1); if(num <= mid) update(num, Tree[rt].L, l, mid); else update(num, Tree[rt].R, mid + 1, r); } int query(int i, int j, int k, int l, int r) { int d = Tree[Tree[j].L].sum - Tree[Tree[i].L].sum; if(l == r) return l; int mid = l + ((r-l)>>1); if(k <= d) return query(Tree[i].L, Tree[j].L, k, l, mid); else return query(Tree[i].R, Tree[j].R, k - d, mid + 1, r); } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%d", &Value[i].x); Value[i].id = i; } //进行离散化 sort(Value + 1, Value + n + 1, cmp); for(int i = 1; i <= n; i++) { Rank[Value[i].id] = i; } init(); for(int i = 1; i <= n; i++) { root[i] = root[i - 1]; update(Rank[i], root[i], 1, n); } int left, right, k;for(int i = 1; i <= m; i++) { scanf("%d%d%d", &left, &right, &k); printf("%d\n", Value[query(root[left - 1], root[right], k, 1, n)].x); } } return 0; }
#include<cstdio> using namespace std; #define N 500001 struct Node{int v,lc,rc;}T[N*21]; int root[N],e; void Insert(int pre,int cur,int p,int l,int r) { if(l==r) { T[cur].v=T[pre].v+1; return; } int m=(l+r>>1); if(p<=m) { T[cur].lc=++e; T[cur].rc=T[pre].rc; Insert(T[pre].lc,T[cur].lc,p,l,m); } else { T[cur].rc=++e; T[cur].lc=T[pre].lc; Insert(T[pre].rc,T[cur].rc,p,m+1,r); } T[cur].v=T[T[cur].lc].v+T[T[cur].rc].v; } int Goal; int Query(int L,int R,int l,int r) { if(l==r) return l; int m=(l+r>>1); if(T[T[R].lc].v-T[T[L].lc].v>Goal) return Query(T[L].lc,T[R].lc,l,m); else if(T[T[R].rc].v-T[T[L].rc].v>Goal) return Query(T[L].rc,T[R].rc,m+1,r); return 0; } int n,m; int main() { int x,y; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) { scanf("%d",&x); root[i]=++e; Insert(root[i-1],root[i],x,1,n); } for(;m;--m) { scanf("%d%d",&x,&y); Goal=(y-x+1>>1); printf("%d\n",Query(root[x-1],root[y],1,n)); } return 0; }
标签:oal iostream for ring 线段树 cst efi scanf date
原文地址:https://www.cnblogs.com/--lr/p/9784239.html