在下可能是被秀了,又调了2h+,接近3h,,
去重时要减一!!
要减一!!
减一!!
这是一个悲伤的故事,不减会在BZOJ上RE(为什么洛谷上不会...),然后就是最后一个输出不输出空格,不然BZOJ上PE(洛谷上还是不会...)
主席树裸题,具体操作都会,在下就不乱扯了,把主席树从序列上改到树上就行了
说的那么玄,其实就是root[i]从root[i-1]来变成从root[fa[i]]来就行了
查询区间为:root[u]的线段树+root[v]的线段树-root[lca(u,v)]的线段树-root[fa[lca(u,v)]]的线段树
偷懒不想树剖,直接倍增了
这次没写注释,需要请留言
#include<bits/stdc++.h> #include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<deque> #include<list> #include<set> #include<vector> #include<iostream> #define ll long long #define re register #define inf 0x3f3f3f3f #define inl inline #define sqr(x) (x*x) //#define eps 1e-8 #define debug printf("debug "); //#pragma comment(linker, "/STACK:1024000000,1024000000") //#pragma GCC optimize (2) //#pragma G++ optimize (2) using namespace std; //const ll mod; const ll MAXN=1e5+10; inl ll read() { re ll x = 0; re int f = 1; char ch = getchar(); while(ch<'0'||ch>'9') { if(ch== '-' ) f = -1; ch = getchar(); } while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x * f; } inl char readc() { char ch=getchar(); while(('z'<ch||ch<'a')&&('Z'<ch||ch<'A')) ch=getchar(); return ch; } inl void write(re ll x){ if(x>=10)write(x/10); putchar(x%10+'0'); } inl void writeln(re ll x){ if(x<0) {x=-x;putchar('-');} write(x); puts(""); } inl ll gcd(re ll x,re ll y){while(y^=x^=y^=x%=y);return x;} inl void FR() { freopen(".in","r",stdin); freopen(".out","w",stdout); } inl void FC() { fclose(stdin); fclose(stdout); } ll n,m,ssw[MAXN],cnt,head[MAXN],fa[MAXN][25],depth[MAXN],tot,root[MAXN]; ll cpy[MAXN],top; struct Node { ll u,v,nxt; }e[MAXN<<1]; struct NODE { ll lson,rson,cnt; }ss[MAXN<<5]; inl void adde(ll u,ll v) { e[++cnt].nxt=head[u];head[u]=cnt; e[cnt].u=u;e[cnt].v=v; } inl void update(ll x) {ss[x].cnt=ss[ss[x].lson].cnt+ss[ss[x].rson].cnt;} ll insert(ll x,ll l,ll r,ll pos) { ll t=++tot;ss[t]=ss[x];ss[t].cnt++; if(l==r) return t; re ll mid=(l+r)>>1; if(pos<=mid) ss[t].lson=insert(ss[x].lson,l,mid,pos); else ss[t].rson=insert(ss[x].rson,mid+1,r,pos); update(t); return t; } void dfs(ll x,ll Fa) { root[x]=insert(root[Fa],1,top,ssw[x]); depth[x]=depth[Fa]+1;fa[x][0]=Fa; for(re ll i=1;i<=20;i++) { fa[x][i]=fa[fa[x][i-1]][i-1]; if(fa[x][i]==0) break ; } for(re ll h=head[x];h;h=e[h].nxt) { re ll v=e[h].v; if(v==Fa) continue ; dfs(v,x); } return ; } ll lca(ll x,ll y) { if(depth[x]>depth[y]) swap(x,y); for(re ll i=20;~i;i--) { if(depth[fa[y][i]]<depth[x]) continue ; y=fa[y][i]; } if(x==y) return x; for(re ll i=20;~i;i--) { if(fa[x][i]==fa[y][i]) continue ; x=fa[x][i],y=fa[y][i]; } return fa[x][0]; } ll query(ll x,ll y,ll z,ll s,ll l,ll r,ll k) { if(l==r) return l; ll sc=ss[ss[x].lson].cnt+ss[ss[y].lson].cnt-ss[ss[z].lson].cnt-ss[ss[s].lson].cnt; ll mid=(l+r)>>1; if(sc>=k) return query(ss[x].lson,ss[y].lson,ss[z].lson,ss[s].lson,l,mid,k); else return query(ss[x].rson,ss[y].rson,ss[z].rson,ss[s].rson,mid+1,r,k-sc); } int main(){ // FR(); n=read(),m=read(); top=n; for(re ll i=1;i<=n;i++) ssw[i]=read(),cpy[i]=ssw[i]; sort(cpy+1,cpy+n+1); top=unique(cpy+1,cpy+n+1)-cpy-1; for(re ll i=1;i<=n;i++) ssw[i]=lower_bound(cpy+1,cpy+top+1,ssw[i])-cpy; for(re ll i=1;i<n;i++) { re ll x=read(),y=read(); adde(x,y);adde(y,x); } dfs(1,0);ll lastans=0; for(re ll i=1;i<=m;i++) { ll u=read()^lastans,v=read(),k=read(); ll x=lca(u,v); lastans=cpy[query(root[u],root[v],root[x],root[fa[x][0]],1,top,k)]; write(lastans); if(i!=m) puts(""); } // FC(); return 0; }