#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
#define wzh(x) cerr<<#x<<'='<<x<<endl;
struct DP_DS{
#define mid (l+r>>1)
struct uzi{
int cnt,pos;
uzi *ls,*rs;
};
vector<uzi *>res;
uzi * a[500005];
uzi * new_node(){
auto tmp=new uzi;
res.pb(tmp);
tmp->cnt=0;
tmp->pos=0;
tmp->ls=tmp->rs=NULL;
return tmp;
}
void push_up(uzi *o){
int res=0,pos;
if(o->ls!=NULL)res=o->ls->cnt,pos=o->ls->pos;
if(o->rs!=NULL&&o->rs->cnt>res)res=o->rs->cnt,pos=o->rs->pos;
o->cnt=res;
o->pos=pos;
}
void up(uzi * &o,int l,int r,int x){
if(o==NULL)o=new_node();
if(l==r){
o->cnt=1;
o->pos=l;
return;
}
if(x<=mid)up(o->ls,l,mid,x);
else up(o->rs,mid+1,r,x);
push_up(o);
}
uzi * merge(uzi *x,uzi *y,int l,int r){
if(x==NULL)return y;
if(y==NULL)return x;
if(l==r){
x->cnt=x->cnt+y->cnt;
return x;
}
x->ls=merge(x->ls,y->ls,l,mid);
x->rs=merge(x->rs,y->rs,mid+1,r);
push_up(x);
return x;
}
void _free(uzi *o){
if(o->ls!=NULL)_free(o->ls);
if(o->rs!=NULL)_free(o->rs);
delete o;
}
#undef mid
}T;
struct uzi{
int x,y,val;
bool operator < (const uzi & t)const{
return val<t.val;
}
}p[N];
int t,n,m,q,a[N],f[N];
int find(int x){
return f[x]==x?x:(f[x]=find(f[x]));
}
int MX=1e6,son[N][2],cnt,val[N],dep[N],fa[N][20],ans[N];
void dfs(int now,int pa){
dep[now]=dep[pa]+1;
fa[now][0]=pa;
for(int i=1;i<20;i++)fa[now][i]=fa[fa[now][i-1]][i-1];
if(now<=n){
ans[now]=a[now];
return;
}
dfs(son[now][0],now);
dfs(son[now][1],now);
T.a[now]=T.merge(T.a[son[now][0]],T.a[son[now][1]],1,MX);
ans[now]=T.a[now]->pos;
}
int CASE;
int main() {
for(scanf("%d",&t);t;t--){
scanf("%d%d",&n,&m);cnt=n;
for(int i=1;i<=n;i++){
scanf("%d", a + i);
T.a[i]=T.new_node();
T.up(T.a[i],1,MX,a[i]);
f[i]=i;
}
for(int i=1;i<=m;i++)scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].val);
sort(p+1,p+1+m);
printf("Case #%d:\n",++CASE);
for(int i=1;i<=m;i++){
int l=find(p[i].x),r=find(p[i].y);
if(l==r)continue;
++cnt;
val[cnt]=p[i].val;
son[cnt][0]=l;
son[cnt][1]=r;
f[cnt]=cnt;
f[l]=f[r]=cnt;
}
dfs(cnt,0);
scanf("%d",&q);int last=0;
for(int i=1;i<=q;i++){
int x,y;
scanf("%d%d",&x,&y);
x^=last;
y^=last;
for(int j=19;j>=0;j--){
if(fa[x][j] && val[fa[x][j]]<=y)x=fa[x][j];
}
printf("%d\n",last=ans[x]);
}
for(auto k:T.res){
delete k;
}
T.res.clear();
}
return 0;
}
2016-2017 ACM-ICPC CHINA-Final G.Pandaria
最新推荐文章于 2021-03-09 15:09:30 发布
本文探讨了使用GCC编译器优化级别2和3的C++代码,重点讲解了一个基于区间更新的动态规划结构(DP_DS),用于解决范围查询问题。通过`uzi`结构和`T`类,作者实现了区间树(区间更新合并)的数据结构,用于高效地处理大量数据的查询。涉及的主要技术包括递归、分治和合并操作,适用于竞赛编程和算法优化场景。
摘要由CSDN通过智能技术生成