#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1e5+10;
int L[20*maxn],R[20*maxn],T[20*maxn],sum[20*maxn],a[maxn],b[maxn];
int tot;void build(int& rt,int l,int r){///建立空树T[0]rt=++tot;sum[rt]=0;if(l==r) return ;int mid=(l+r)>>1;build(L[rt],l,mid);build(R[rt],mid+1,r);
}
///对所有前缀更新树
void update(int& rt,int pre,int l,int r,int pos){rt = ++tot;L[rt]=L[pre];R[rt]=R[pre];sum[rt]=sum[pre]+1;if(l==r) return ;int mid=(l+r)/2;if(pos<=mid) update(L[rt],L[pre],l,mid,pos);else update(R[rt],R[pre],mid+1,r,pos);
}
///二分查找
int query(int s,int e,int l,int r,int k){if(l==r) return l;int res=sum[L[e]]-sum[L[s]];int mid=(l+r)/2;if(k<=res) return query(L[s],L[e],l,mid,k);else return query(R[s],R[e],mid+1,r,k-res);
}int main(){int t,n,m;cin>>t;while(t--){tot=0;cin>>n>>m;for(int i=1;i<=n;i++) cin>>a[i],b[i]=a[i];///离散化 使用 sort + unique + lower_bound 比较方便 map也行 或者二分查找sort(b+1,b+n+1);int num=unique(b+1,b+n+1)-b-1;build(T[0],1,num);for(int i=1;i<=n;i++)update(T[i],T[i-1],1,num,lower_bound(b+1,b+num+1,a[i])-b);///(先排序)lower_bounder函数返回第一个大于或者等于该元素的下标while(m--) {int s,e,k;cin>>s>>e>>k;int ans=query(T[s-1],T[e],1,num,k);cout<<b[ans]<<endl;}}
}
第二组样例构造的序列:
1
2
3 1
4 3 1
5 2
6 5 2
7 5 2
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+5;
int t,n,k,a[N],ans[N],pos[N];
int rt[N*20],ls[N*20],rs[N*20],sum[N*20],cnt=0;void up(int pre,int& o,int l,int r,int pos) {o=++cnt;ls[o]=ls[pre];rs[o]=rs[pre];sum[o]=sum[pre]+1;if(l==r) return ;int m=(l+r)/2;if(pos<=m) up(ls[pre],ls[o],l,m,pos);else up(rs[pre],rs[o],m+1,r,pos);
}int qu(int pre,int o,int l,int r,int kk) {if(l==r) {if(l>kk) return -1;return l;}int m=(l+r)/2;if(kk>m && sum[rs[o]]-sum[rs[pre]]) {int ans = qu(rs[pre],rs[o],m+1,r,kk);if(ans==-1) {if(kk>=l && sum[ls[o]]-sum[ls[pre]])return qu(ls[pre],ls[o],l,m,kk);return -1;}else return ans;}if(kk>=l && sum[ls[o]]-sum[ls[pre]])return qu(ls[pre],ls[o],l,m,kk);return -1;
}int main(){scanf("%d",&t);while(t--) {cnt = 0;scanf("%d%d",&n,&k);for(int i=1;i<=n;i++) {scanf("%d",&a[i]);pos[a[i]]=i;up(rt[i-1],rt[i],1,n,a[i]);}for(int i=1;i<=n;i++) {int l=max(1,pos[i]-k),r=min(n,pos[i]+k);int s1=qu(rt[l-1],rt[pos[i]-1],1,n,i-1);int s2=qu(rt[pos[i]],rt[r],1,n,i-1);int res = max(s1,s2);if(res==-1) ans[i] = 1;else ans[i] = ans[res]+1;}for(int i=1;i<n;i++) printf("%d ",ans[i]);printf("%dn",ans[n]);}return 0;
}
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;const int N = 100007;int n, m, num, n1, n2;
int a[N], b[N << 1], c[N], d[N], e[N], t1[N], t2[N];
int Top, Root[N], val[N * 400], ls[N * 400], rs[N * 400];inline int lowbit(int x) {return x & (-x);
}void Add(int &rt, int l, int r, int ind, int c) {if (!rt) rt = ++Top;val[rt] += c;if (l == r) return;int m = (l + r) >> 1;if (ind <= m) Add(ls[rt], l, m, ind, c);else Add(rs[rt], m+1, r, ind, c);
}void Change(int ind, int val) {int x = lower_bound(b + 1, b + 1 + num, a[ind]) - b;for (int i = ind; i <= n; i += lowbit(i))Add(Root[i], 1, num, x, val);
}int Kth(int l, int r, int k) { ///求第 k 大if (l == r) return l;int m = (l + r) >> 1, sum = 0;for (int i = 1; i <= n2; ++i)sum += val[ls[t2[i]]];for (int i = 1; i <= n1; ++i)sum -= val[ls[t1[i]]];if (sum >= k) {for (int i = 1; i <= n1; ++i) ///所有树的节点保持对应t1[i] = ls[t1[i]];for (int i = 1; i <= n2; ++i)t2[i] = ls[t2[i]];return Kth(l, m, k);} else {for (int i = 1; i <= n1; ++i)t1[i] = rs[t1[i]];for (int i = 1; i <= n2; ++i)t2[i] = rs[t2[i]];return Kth(m+1, r, k - sum);}
}int Kth_pre(int l, int r, int k) {n1 = n2 = 0;for (int i = l - 1; i >= 1; i -= lowbit(i)) ///处理出需要求和的 n1 棵树t1[++n1] = Root[i];for (int i = r; i >= 1; i -= lowbit(i))t2[++n2] = Root[i];return Kth(1, num, k);
}int main(){///读入scanf("%d%d", &n, &m);for (int i = 1; i <= n; ++i) {scanf("%d", &a[i]);b[++num] = a[i];}for (int i = 1; i <= m; ++i) {char ch = getchar();while (ch != 'Q' && ch != 'C')ch = getchar();if (ch == 'Q')scanf("%d%d%d", &c[i], &d[i], &e[i]);else {scanf("%d%d", &c[i], &d[i]);b[++num] = d[i]; ///对于所有出现过的值(包括插入操作中的值)离散化}}///离散化sort(b + 1, b + 1 + num);num = unique(b + 1, b + 1 + num) - b - 1;///建树for (int i = 1; i <= n; ++i)Change(i, 1);///处理操作&询问 因为要离散化所以要离线处理for (int i = 1; i <= m; ++i) {if (e[i]) {printf("%dn", b[Kth_pre(c[i], d[i], e[i])]);} else {Change(c[i], -1);a[c[i]] = d[i];Change(c[i], 1);}}return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 3e5+5;
int n,q,a[N];int rt[N*20],ls[N*20],rs[N*20],sum[N*20],cnt=0;
void up(int pre,int& o,int l,int r,int pos) {o=++cnt;ls[o]=ls[pre];rs[o]=rs[pre];sum[o]=sum[pre]+1;if(l==r) return ;int m=(l+r)/2;if(pos<=m) up(ls[pre],ls[o],l,m,pos);else up(rs[pre],rs[o],m+1,r,pos);
}int qu(int pre,int o,int l,int r,int k) {if(l==r) return l;int m=(l+r)/2;if(sum[ls[o]]-sum[ls[pre]]>k) {int res = qu(ls[pre],ls[o],l,m,k);if(res != -1) return res;}if(sum[rs[o]]-sum[rs[pre]]>k) {int res = qu(rs[pre],rs[o],m+1,r,k);if(res != -1) return res;}return -1;
}int main(){scanf("%d%d",&n,&q);for(int i=1;i<=n;i++) {scanf("%d",&a[i]);up(rt[i-1],rt[i],1,n,a[i]);}while(q--) {int l,r,k;scanf("%d%d%d",&l,&r,&k);int ans = qu(rt[l-1],rt[r],1,n,(r-l+1)/k);printf("%dn",ans);}return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
int n,q,a[N],p[N];int rt[N*40],ls[N*40],rs[N*40],sum[N*40],cnt=0;
void up(int pre,int& o,int l,int r,int pos,int val) {o=++cnt;ls[o]=ls[pre];rs[o]=rs[pre];sum[o]=sum[pre]+val;if(l==r) return ;int m=(l+r)/2;if(pos<=m) up(ls[pre],ls[o],l,m,pos,val);else up(rs[pre],rs[o],m+1,r,pos,val);
}int qu(int o,int l,int r,int ql,int qr) {if( ql<=l && qr>=r ) return sum[o];int ans = 0,m = (l+r)/2;if(ql<=m) ans += qu(ls[o],l,m,ql,qr);if(qr>m) ans += qu(rs[o],m+1,r,ql,qr);return ans;
}int main(){scanf("%d",&n);for(int i=1;i<=n;i++) {scanf("%d",&a[i]);if(!p[a[i]]) {up(rt[i-1],rt[i],1,n,i,1);}else {int tp;up(rt[i-1],tp,1,n,p[a[i]],-1);up(tp,rt[i],1,n,i,1);}p[a[i]] = i;}scanf("%d",&q);while(q--) {int l,r;scanf("%d%d",&l,&r);int ans = qu(rt[r],1,n,l,r);printf("%dn",ans);}return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5+5;
const int M = 1e9;int rt[N*30],ls[N*30],rs[N*30],mn[N*30],cnt=0;
void up(int pre,int& o,int l,int r,int val,int pos) {o=++cnt;ls[o]=ls[pre];rs[o]=rs[pre];mn[o]=pos;if(l==r) return ;int m=(l+r)/2;if(val<=m) up(ls[pre],ls[o],l,m,val,pos);else up(rs[pre],rs[o],m+1,r,val,pos);mn[o]=min(mn[ls[o]],mn[rs[o]]);
}int qu(int o,int l,int r,int pos) {if(l==r) return l;int m=(l+r)/2;if( mn[ls[o]]<pos ) return qu(ls[o],l,m,pos);return qu(rs[o],m+1,r,pos);
}int a[N],n,q,l,r;
int main(){scanf("%d%d",&n,&q);for(int i=1;i<=n;i++) {scanf("%d",&a[i]);up(rt[i-1],rt[i],0,M,a[i],i);}while(q--) {scanf("%d%d",&l,&r);int ans = qu(rt[r],0,M,l);printf("%dn",ans);}return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+1;int rt[N],ls[N*200],rs[N*200],sum[N*200],cnt=0;
void up(int pre,int& o,int l,int r,int pos) {o=++cnt;ls[o]=ls[pre];rs[o]=rs[pre];sum[o]=sum[pre]+1;if(l==r) return ;int m=(l+r)/2;if(pos<=m) up(ls[pre],ls[o],l,m,pos);else up(rs[pre],rs[o],m+1,r,pos);
}int qu(int o,int l,int r,int ql,int qr) {if( ql<=l && qr>=r ) return sum[o];int m=(l+r)/2,ans=0;if(ql<=m) ans += qu(ls[o],l,m,ql,qr);if(qr>m) ans += qu(rs[o],m+1,r,ql,qr);return ans;
}int n,q,l,r,a[N],p[N];
vector<int> g[N];
int main(){scanf("%d%d",&n,&q);for(int i=1;i<=n;i++) {scanf("%d",&a[i]);p[a[i]]=i;}for(int i=1;i<=n;i++) {for(int j=2*i;j<=n;j+=i) {///防止重复计数if (p[i] < p[j]) g[p[j]].push_back(p[i]);if (p[i] > p[j]) g[p[i]].push_back(p[j]);}}for(int i=1;i<=n;i++) {rt[i] = rt[i-1];///技巧for(auto u:g[i])up(rt[i],rt[i],1,n,u);}while(q--) {scanf("%d%d",&l,&r);int ans = qu(rt[r],1,n,l,r);printf("%dn",ans);}return 0;
}
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 3e4 + 10, mod = 10007;
vector<int> g[N];
char s[N];struct nd {int ABCBA, A, AB, ABC, ABCB, B, BC, BCB, BCBA, C, CB, CBA, BA;nd operator+(const nd &t) const {nd tmp;tmp.ABCBA = (ABCBA + t.ABCBA + A * t.BCBA + AB * t.CBA + ABC * t.BA + ABCB * t.A) % mod;tmp.A = (A + t.A) % mod;tmp.AB = (AB + t.AB + A * t.B) % mod;tmp.ABC = (ABC + t.ABC + A * t.BC + AB * t.C) % mod;tmp.ABCB = (ABCB + t.ABCB + A * t.BCB + AB * t.CB + ABC * t.B) % mod;tmp.B = (B + t.B) % mod;tmp.BC = (BC + t.BC + B * t.C) % mod;tmp.BCB = (BCB + t.BCB + B * t.CB + BC * t.B) % mod;tmp.BCBA = (BCBA + t.BCBA + B * t.CBA + BC * t.BA + BCB * t.A) % mod;tmp.C = (C + t.C) % mod;tmp.CB = (CB + t.CB + C * t.B) % mod;tmp.CBA = (CBA + t.CBA + C * t.BA + CB * t.A) % mod;tmp.BA = (BA + t.BA + B * t.A) % mod;return tmp;}
}tr[N * 20];
int rt[N], ls[N * 20], rs[N * 20], cnt, f[N][20], dep[N], n;
#define mid (l + r) / 2
void up(int &o, int pre, int l, int r, int k, char c) {o = ++cnt;ls[o] = ls[pre];rs[o] = rs[pre];if (l == r) {if (c == 'A')tr[o].A = 1;else if (c == 'B')tr[o].B = 1;else if (c == 'C')tr[o].C = 1;return;}if (k <= mid)up(ls[o], ls[pre], l, mid, k, c);elseup(rs[o], rs[pre], mid + 1, r, k, c);tr[o] = tr[ls[o]] + tr[rs[o]];
}void dfs(int u, int fa) {f[u][0] = fa;dep[u] = dep[fa] + 1;for (int i = 1; i < 18; i++)f[u][i] = f[f[u][i - 1]][i - 1];up(rt[u], rt[fa], 1, n, dep[u], s[u]);for (auto v : g[u])if (v != fa)dfs(v, u);
}int LCA(int u, int v) {if (dep[u] < dep[v])swap(u, v);for (int i = 17; ~i; i--)if (dep[f[u][i]] >= dep[v])u = f[u][i];if (u == v)return u;for (int i = 17; ~i; i--)if (f[u][i] != f[v][i])u = f[u][i], v = f[v][i];return f[u][0];
}nd qu(int o, int l, int r, int ql, int qr) {if (l >= ql && r <= qr)return tr[o];if (qr <= mid)return qu(ls[o], l, mid, ql, qr);else if (ql > mid)return qu(rs[o], mid + 1, r, ql, qr);elsereturn qu(ls[o], l, mid, ql, qr) + qu(rs[o], mid + 1, r, ql, qr);
}int main() {int m, u, v;scanf("%d%d", &n, &m);scanf("%s", s + 1);for (int i = 1; i < n; i++) {scanf("%d%d", &u, &v);g[u].push_back(v);g[v].push_back(u);}dfs(1, 0);while (m--) {scanf("%d%d", &u, &v);int lca = LCA(u, v);int ans = 0;nd tmp;if(u==lca) {ans = qu(rt[v], 1, n, dep[lca], dep[v]).ABCBA;}else if(v==lca) {ans = qu(rt[u], 1, n, dep[lca], dep[u]).ABCBA;}else {/// u-lca v-lca 正反都行 因为ABCBA回文nd t1 = qu(rt[v], 1, n, dep[lca], dep[v]);nd t2 = qu(rt[u], 1, n, dep[lca] + 1, dep[u]);ans = (t1.ABCBA + t2.ABCBA + t1.A * t2.BCBA + t1.BA * t2.CBA + t1.CBA * t2.BA + t1.BCBA * t2.A) % mod;}printf("%dn", ans);}return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e6+5;
int n,m,qq,f[N];
struct nd{int u,v,w;
}e[N];
bool cmp(nd x,nd y) {return x.w<y.w;
}int fd(int x) {if(x==f[x]) return x;else return f[x]=fd(f[x]);
}struct Node{int x, y, z;
}q[N],hh[N];vector<int> g[N];
int wt[N],num;///点权和总点数///克鲁斯卡尔重构树
void kru() {sort(e+1,e+m+1,cmp);for(int i=1;i<N;i++) f[i] = i;for(int i=1;i<=m;i++) {int x=fd(e[i].u),y=fd(e[i].v);if(x != y) {wt[++num] = e[i].w;g[num].push_back(x);g[num].push_back(y);f[x] = f[y] = num;}}
}int dep[N],fa[N][20],L[N],R[N],b[N],c[N],sz,tot;
void dfs(int pre,int u) {dep[u] = dep[pre] + 1;fa[u][0] = pre;for(int i=1;i<20;i++)fa[u][i] = fa[fa[u][i-1]][i-1];L[u] = tot;if(g[u].size() == 0) {b[++tot] = u;R[u] = tot;return ;}for(auto v:g[u])dfs(u,v);R[u] = tot;
}
///主席树求第k大
int rt[N],ls[N*20],rs[N*20],sum[N*20],cnt=0;
void up(int pre,int& o,int l,int r,int pos) {o=++cnt;ls[o]=ls[pre];rs[o]=rs[pre];sum[o]=sum[pre]+1;if(l==r) return ;int m=(l+r)/2;if(pos<=m) up(ls[pre],ls[o],l,m,pos);else up(rs[pre],rs[o],m+1,r,pos);
}int qu(int pre,int o,int l,int r,int k) {if(l==r) return l;int m=(l+r)/2;if(sum[ls[o]]-sum[ls[pre]]>=k) return qu(ls[pre],ls[o],l,m,k);else return qu(rs[pre],rs[o],m+1,r,k-(sum[ls[o]]-sum[ls[pre]]));
}int h[N];
void solve() {kru();dfs(num,num);///注意以什么离散化,不要搞混了for(int i=1;i<=tot;i++)up(rt[i-1],rt[i],1,n,h[b[i]]);while(qq--) {int v,x,k;scanf("%d%d%d",&v,&x,&k);for(int i=19;i>=0;i--)if(fa[v][i] && wt[fa[v][i]] <= x) v = fa[v][i]; ///找到深度最小且点权不大于k的祖先if(R[v]-L[v]<k) puts("-1");else {int ans = qu(rt[L[v]],rt[R[v]],1,n,R[v]-L[v]-k+1);printf("%dn",hh[ans].z);}}
}bool cmp1(Node x, Node y){return x.z < y.z;
}int main(){scanf("%d%d%d",&n,&m,&qq);for(int i=1;i<=n;i++) scanf("%d",&h[i]);///离散化部分,先将h数组离散化for(int i = 1; i <= n; i++) hh[i].x = i, hh[i].z = h[i];sort(hh + 1, hh + n + 1, cmp1);for(int i = 1; i <= n; i++) h[hh[i].x] = i;num = n;for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);solve();return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e6+5;
int n,q,dep[N],dfn[N],son[N],tot,mxdep;
vector<int> g[N];int rt[N],ls[N*20],rs[N*20],cnt=0;
ll sum[20*N];
void up(int pre,int& o,int l,int r,int pos,int val) {o=++cnt;ls[o]=ls[pre];rs[o]=rs[pre];sum[o]=sum[pre]+val;if(l==r) return ;int m=(l+r)/2;if(pos<=m) up(ls[pre],ls[o],l,m,pos,val);else up(rs[pre],rs[o],m+1,r,pos,val);///sum[o]=sum[ls[o]]+sum[rs[o]];加不加都行
}ll qu(int pre,int o,int l,int r,int ql,int qr) {if(ql <= l && qr >= r) return sum[o]-sum[pre];int m=(l+r)/2;ll ans = 0;if(ql<=m) ans += qu(ls[pre],ls[o],l,m,ql,qr);if(qr>m) ans += qu(rs[pre],rs[o],m+1,r,ql,qr);return ans;
}void dfs(int u,int fa) {son[u] = 1;dfn[u] = ++tot;dep[u] = dep[fa] + 1;mxdep = max(mxdep,dep[u]);for(auto v:g[u]) {if(v==fa) continue;dfs(v,u);son[u] += son[v];}
}void dfs2(int u,int fa) {up(rt[dfn[u]-1],rt[dfn[u]],1,mxdep,dep[u],son[u]-1);for(auto v:g[u]) {if(v==fa) continue;dfs2(v,u);}
}int main(){scanf("%d%d",&n,&q);for(int i=1;i<n;i++) {int u,v;scanf("%d%d",&u,&v);g[u].push_back(v);g[v].push_back(u);}dfs(1,0);dfs2(1,0);while(q--) {int p,k;scanf("%d%d",&p,&k);ll ans=1LL*(son[p]-1)*min(dep[p]-1,k);ans += qu(rt[dfn[p]],rt[dfn[p]+son[p]-1],1,mxdep,min(mxdep,dep[p]+1),min(mxdep,dep[p]+k));printf("%lldn",ans);}return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5+5;
int n,q,a[N],b[N],sz;
vector<int> g[N];int rt[N],ls[N*20],rs[N*20],sum[N*20],cnt=0;
void up(int pre,int& o,int l,int r,int pos) {o=++cnt;ls[o]=ls[pre];rs[o]=rs[pre];sum[o]=sum[pre]+1;if(l==r) return ;int m=(l+r)/2;if(pos<=m) up(ls[pre],ls[o],l,m,pos);else up(rs[pre],rs[o],m+1,r,pos);
}int qu(int u,int v,int lca,int flca,int l,int r,int k) {if(l==r) return b[l];int m=(l+r)/2;int num = sum[ls[u]]-sum[ls[lca]]+sum[ls[v]]-sum[ls[flca]];if(num>=k) return qu(ls[u],ls[v],ls[lca],ls[flca],l,m,k);return qu(rs[u],rs[v],rs[lca],rs[flca],m+1,r,k-num);
}int dep[N],f[N][20];
void dfs(int u,int fa) {dep[u] = dep[fa] + 1;f[u][0] = fa;for(int i = 1; i<20; i++)f[u][i] = f[f[u][i-1]][i-1];int pos = lower_bound(b+1,b+1+sz,a[u]) - b;up(rt[fa],rt[u],1,sz,pos);for(auto v:g[u]) {if(v==fa) continue;dfs(v,u);}
}int LCA(int u,int v) {if(dep[u]<dep[v]) swap(u,v);///注意是交换u和v,不是交换dep[u]和dep[v]int d=dep[u]-dep[v];for(int i=0;i<20;i++)///先调整到同一深度if(d&(1<<i)) u=f[u][i];if(u==v) return u;for(int i=19;i>=0;i--) {///注意是倒着for,二进制拆分,从大到小尝试if(f[u][i]!=f[v][i]) {u=f[u][i];v=f[v][i];}}return f[u][0];
}int main(){scanf("%d%d",&n,&q);for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];sort(b+1,b+1+n);sz = unique(b+1,b+1+n) - b - 1;for(int i=1;i<n;i++) {int u,v;scanf("%d%d",&u,&v);g[u].push_back(v);g[v].push_back(u);}dfs(1,0);int last=0,u,v,k,lca,flca;while(q--) {scanf("%d%d%d",&u,&v,&k);u^=last;lca = LCA(u,v);flca = f[lca][0];last = qu(rt[u],rt[v],rt[lca],rt[flca],1,sz,k);printf("%dn",last);}return 0;
}
本文发布于:2024-01-30 06:09:42,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170656618619785.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |