1. 程式人生 > >jzoj 5850.【NOIP提高組模擬2018.8.25】e 可持久化線段樹+lca

jzoj 5850.【NOIP提高組模擬2018.8.25】e 可持久化線段樹+lca

Description
這裡寫圖片描述
Input
這裡寫圖片描述
Output
這裡寫圖片描述
Data Constraint
這裡寫圖片描述

分析:
最小連通塊可以看作是所有點到他們的lca路徑的並集,因為是取最小值,所以重複的不會有貢獻。
我們對這棵樹建可持久化線段樹,每個點的線段樹相當於他的父親加上一條鏈。然後就相當於在這些線段樹上找前驅與後繼。
一開始我想到二分答案,再判斷,這樣做是O(nlog2n)的,然後我被卡掉了。然後還有一種直接線段樹找前驅的方法,如果當前點小於mid,直接找左半部分,否則先找右半部分,如果沒有再找左半部,這樣做應該是和k-d tree找最近點對差不多的。

程式碼:

#include <iostream>
#include <cstdio>
#include <cmath>

const int maxn=1e5+7;
const int maxp=1e9;

using namespace std;

int n,test,m,typ,x,y,cnt,l,r,lastans;
int a[maxn],root[maxn],f[maxn][20],b[maxn*3],ls[maxn],dep[maxn];

struct node{
    int l,r,data;
}t[maxn*50];

struct edge{
    int
y,next; }g[maxn*2]; void add(int x,int y) { g[++cnt]=(edge){y,ls[x]}; ls[x]=cnt; } void ins(int &p,int q,int l,int r,int x,int k) { if (!p) p=++cnt; t[p].data=t[q].data+k; if (l==r) return; int mid=(l+r)/2; if (x<=mid) t[p].r=t[q].r,ins(t[p].l,t[q].l,l,mid,x,k); else
t[p].l=t[q].l,ins(t[p].r,t[q].r,mid+1,r,x,k); } int getpre(int p,int q,int l,int r,int x) { if (!(t[p].data-t[q].data)) return 0; if (l==r) return l; int mid=(l+r)/2; if (x<=mid) return getpre(t[p].l,t[q].l,l,mid,x); else { int tmp=getpre(t[p].r,t[q].r,mid+1,r,x); if (tmp) return tmp; return getpre(t[p].l,t[q].l,l,mid,x); } } int getnext(int p,int q,int l,int r,int x) { if (!(t[p].data-t[q].data)) return 0; if (l==r) return l; int mid=(l+r)/2; if (x>mid) return getnext(t[p].r,t[q].r,mid+1,r,x); else { int tmp=getnext(t[p].l,t[q].l,l,mid,x); if (tmp) return tmp; return getnext(t[p].r,t[q].r,mid+1,r,x); } } void dfs(int x,int fa) { f[x][0]=fa; dep[x]=dep[fa]+1; ins(root[x],root[fa],1,maxp,a[x],1); for (int i=ls[x];i>0;i=g[i].next) { int y=g[i].y; if (y==fa) continue; dfs(y,x); } } int lca(int x,int y) { if (dep[x]>dep[y]) swap(x,y); int d=dep[y]-dep[x],k=19,t=1<<k; while (d) { if (d>=t) d-=t,y=f[y][k]; t/=2,k--; } if (x==y) return x; k=19; while (k>=0) { if (f[x][k]!=f[y][k]) { x=f[x][k]; y=f[y][k]; } k--; } return f[x][0]; } int main() { freopen("e.in","r",stdin); freopen("e.out","w",stdout); scanf("%d%d%d",&n,&test,&typ); for (int i=1;i<=n;i++) scanf("%d",&a[i]); for (int i=1;i<n;i++) { scanf("%d%d",&x,&y); add(x,y); add(y,x); } cnt=0; dfs(1,0); for (int j=1;j<20;j++) { for (int i=1;i<=n;i++) { f[i][j]=f[f[i][j-1]][j-1]; } } for (int i=1;i<=test;i++) { scanf("%d%d",&x,&m); for (int j=1;j<=m;j++) { scanf("%d",&b[j]); b[j]=(b[j]-1+lastans*typ)%n+1; } int d=b[1]; for (int j=2;j<=m;j++) d=lca(d,b[j]); d=f[d][0]; lastans=2e9; for (int j=1;j<=m;j++) { int tmp1=getpre(root[b[j]],root[d],1,maxp,x); int tmp2=getnext(root[b[j]],root[d],1,maxp,x); if (tmp1) lastans=min(lastans,x-tmp1); if (tmp2) lastans=min(lastans,tmp2-x); } printf("%d\n",lastans); } }

相關推薦

jzoj 5850.NOIP提高模擬2018.8.25e 持久化線段+lca

Description Input Output Data Constraint 分析: 最小連通塊可以看作是所有點到他們的lcalca路徑的並集,因為是取最小值,所以重複的不會有貢獻。 我們對這棵樹建可持久化線段樹,每個點的線段樹相

jzoj 5849.NOIP提高模擬2018.8.25d 排序+權值線段

Description Input Output Data Constraint 分析: 所有矩陣的交集最大面積顯然為min(xi)∗min(yi)min(xi)∗min(yi

[JZOJ5817] NOIP提高A模擬2018.8.15 抄代碼

esp pre col font getch tput lin esc out Description J 君是機房的紅太陽,每次模擬她總是 AK 虐場。然而在 NOIP2117 中,居然出現了另一位 AK 的選手 C 君! 這引起了組委會的懷疑,組委會認為 C 君有

[JZOJ5818] NOIP提高A模擬2018.8.15 做運動

put stdin output 天氣 如果 char 使用 fields 快速 Description 一天,Y 君在測量體重的時候驚訝的發現,由於常年坐在電腦前認真學習,她的體重有了突 飛猛進的增長。 幸好 Y 君現在退役了,她有大量的時間來做運動,她決定每天從

JZOJ5821NOIP提高A模擬2018.8.16 手機信號(set/權值線段

solution 線段 插入 函數 efi putc 所有 water 打了 Problem Hint Solution 這道題就是一道考驗你細節處理的題。 我們用形如(l,r,v)的三元組表示一個區間的信號站,意為從l到r每隔v有一個信號站。 考慮用set/權值線段

[JZOJ 5195] NOIP2017提高模擬7.3A//2018.10.29 {動態規劃}

題目 解題思路動態規劃 我們可以將方案分成兩種: 至少包含一個 111 的; 一個 111 都不包含。 設f[i][j]f[i][j]f[i][j]表示答案,那麼表示111的答案即為f[

JZOJ5811. NOIP提高A模擬2018.8.13簡單的填數

Data Constraint 對於 30% 的資料,n ≤ 1000; 對於另外 30% 的資料,資料保證隨機生成; 對於 100% 的資料,2 ≤ n ≤ 2 × 10^5 , 0 ≤ ai ≤ 10^5。 題解 這個很顯然是特殊構造, 設一

5821. NOIP提高A模擬2018.8.16 手機訊號

題目描述 Input 第一行由一個空格隔開的兩個正整數 m, c,意義見題目描述。 接下來 m 行,每行可能有以下形式: construct l r v 代表發生了第一種事件; destruct l r 代表發生了第二種事件; query x 代

jzoj 5178. NOIP2017提高模擬6.28So many prefix?(kmp+dp)

5178. 【NOIP2017提高組模擬6.28】So many prefix? Description Sample Input 樣例一: abababc 樣例二: isdashagayisdashagaydashisnotagaydashisnotagay Samp

JZOJ 5878. NOIP2018提高模擬9.22電路圖 A

Description nodgd 要畫一個電路圖。 這是一個很簡單的電路圖,所有的元件都是串聯關係,從整體來看就是一個環狀的結構。畫電路圖有很多要求,nodgd 為了畫得好看就又添加了一些 額外的要求。所有要求歸結起來有以下幾點: 1、這個環狀電路上有n個雙端

XSY2732Decalcomania 持久化線段 分治

lin %d == void ret 多少 for size include 題目描述   有一個陶瓷瓶周圍有\(n\)個可以印花的位置。第\(i\)個與第\(i+1\)個位置之間的距離為\(d_i\),在第\(i\)個位置印圖案要\(t_i\)秒。   機器剛開始在\(0

[jzoj]2018.08.09NOIP提高模擬賽C:解題報告

目錄: 1.種類分配(Breed Assignment) 2.資訊傳遞(Message Relay) 3.計算周長(Perimeter) 4.找奶牛(Find the Cow!) 1.種類分配(Breed Assignment) 題目:

2018.12.08NOIP提高模擬B JZOJ 100042 保留道路

描述 很久很久以前有一個國家,這個國家有N個城市,城市由1,2,3,…, N N N標號,城市間有M

2018.12.15NOIP提高模擬B JZOJ 100047 基因變異

題目 JZOJ 100047 基因變異 思路 設 x   x

2018.12.15NOIP提高模擬B JZOJ 100046 收集卡片

題目 JZOJ 100046 收集卡片 思路 維護一個區間,列舉結束訂閱的時間判斷能否晚點訂閱,開一個變數模擬指標維護即可。 ——鳴謝 w

2018.12.22NOIP提高模擬B JZOJ 3519 靈能矩陣

大意 給定一棵樹,規定每個點的權值為其所有葉子節點的權值和,現在只能減少葉子節點的權值,問使所有節點的子節點權值都相同的最少總減少值 資料範圍: 對於15%的資料, 1