JZOJ 5850. 【NOIP提高组模拟2018.8.25】e
生活随笔
收集整理的這篇文章主要介紹了
JZOJ 5850. 【NOIP提高组模拟2018.8.25】e
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description
Input
Output
Sample Input
5 7 0
1 2 3 4 5
1 2
2 3
2 4
1 5
1 2 4 5
2 2 4 5
3 2 4 5
4 2 4 5
5 2 4 5
5 1 2
100 3 1 2 5
Sample Output
0
0
1
0
0
3
95
Data Constraint
Solution
挺不錯的一題!
首先對于一個 kk 個點構成的連通塊,就是那 kk 個點的lca,之后延伸出來許多條鏈。
那么我們先找到那個lca,再對于每一條鏈都找出最接近 rr 的值。
這怎么辦呢?建可持久化的權值線段樹(主席樹)就可以了,查詢 比它大最小的 和 比它小的最大的 兩個值。
我的方法是樹鏈剖分后建樹,在每條重鏈中查詢,但還有更好的方法是每個點從它的父親處繼承。
時間復雜度 O(klog2n)O(klog2n) 。
Code
#include<cstdio> #include<cctype> using namespace std; const int N=1e5+5,inf=1e9; struct data {int v,l,r; }f[N*32]; int tot,last,qx,qy,pos; int first[N],nex[N<<1],en[N<<1]; int fa[N],dep[N],son[N],size[N]; int top[N],pre[N],tree[N]; int a[N],p[N],rt[N]; inline int read() {int X=0,w=0; char ch=0;while(!isdigit(ch)) w|=ch=='-',ch=getchar();while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X; } void write(int x) {if(x>9) write(x/10);putchar(x%10+'0'); } inline void insert(int x,int y) {nex[++tot]=first[x];first[x]=tot;en[tot]=y; } void dfs(int x) {dep[x]=dep[fa[x]]+1;size[x]=1;for(int i=first[x];i;i=nex[i])if(en[i]^fa[x]){fa[en[i]]=x;dfs(en[i]);size[x]+=size[en[i]];if(!son[x] || son[en[i]]>size[son[x]]) son[x]=en[i];} } void dfs1(int x,int y) {top[pre[tree[x]=++tot]=x]=y;if(!son[x]) return;dfs1(son[x],y);for(int i=first[x];i;i=nex[i])if(en[i]^fa[x] && en[i]^son[x]) dfs1(en[i],en[i]); } int lca(int x,int y) {while(top[x]^top[y])if(dep[top[x]]>dep[top[y]]) x=fa[top[x]]; else y=fa[top[y]];return dep[x]<dep[y]?x:y; } inline int abs(int x) {return x<0?-x:x; } inline int min(int x,int y) {return x<y?x:y; } void change(int ff,int &v,int l,int r) {f[v=++tot]=f[ff];f[v].v++;if(l==r) return;int mid=l+r>>1;if(pos<=mid) change(f[ff].l,f[v].l,l,mid); else change(f[ff].r,f[v].r,mid+1,r); } int down(int ff,int v,int l,int r) {if(!(f[v].v-f[ff].v)) return 0;if(l==r) return l;int mid=l+r>>1;if(qx<=mid) return down(f[ff].l,f[v].l,l,mid);int s=down(f[ff].r,f[v].r,mid+1,r);return s?s:down(f[ff].l,f[v].l,l,mid); } int up(int ff,int v,int l,int r) {if(!(f[v].v-f[ff].v)) return 0;if(l==r) return l;int mid=l+r>>1;if(qx>mid) return up(f[ff].r,f[v].r,mid+1,r);int s=up(f[ff].l,f[v].l,l,mid);return s?s:up(f[ff].r,f[v].r,mid+1,r); } int main() {freopen("e.in","r",stdin);freopen("e.out","w",stdout);int n=read(),q=read(),ty=read();if(!q) return 0;for(int i=1;i<=n;i++) a[i]=read();for(int i=1;i<n;i++){int x=read(),y=read();insert(x,y);insert(y,x);}tot=0;dfs(1);dfs1(1,1);tot=0;for(int i=1;i<=n;i++) pos=a[pre[i]],change(rt[i-1],rt[i],1,inf);while(q--){int r=read(),k=read();for(int i=1;i<=k;i++) p[i]=(read()-1+last*ty)%n+1;pos=p[1];for(int i=2;i<=k && pos>1;i++) pos=lca(pos,p[i]);last=abs(a[pos]-r);qx=r;for(int i=1;i<=k && last;i++){int x=p[i];while(top[x]^top[pos]){int num=down(rt[tree[top[x]]-1],rt[tree[x]],1,inf);if(num) last=min(last,abs(num-r));num=up(rt[tree[top[x]]-1],rt[tree[x]],1,inf);if(num) last=min(last,abs(num-r));x=fa[top[x]];}int num=down(rt[tree[pos]-1],rt[tree[x]],1,inf);if(num) last=min(last,abs(num-r));num=up(rt[tree[pos]-1],rt[tree[x]],1,inf);if(num) last=min(last,abs(num-r));}write(last),putchar('\n');}return 0; } 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的JZOJ 5850. 【NOIP提高组模拟2018.8.25】e的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JZOJ 5820. 【NOIP提高A组
- 下一篇: JZOJ 5878. 【NOIP2018