題目大意:有兩個操作,1:在第x次操作後的版本上修改乙個值,2:查詢在第x次操作後的版本上的乙個節點的值
即:你需要維護這樣的乙個長度為n的陣列,支援如下幾種操作
1.在某個歷史版本上修改某乙個位置上的值
2.訪問某個歷史版本上的某一位置的值
此外,每進行一次操作(對於操作2,即為生成乙個完全一樣的版本,不作任何改動),就會生成乙個新的版本。版本編號即為當前操作的編號(從1開始編號,版本0表示初始狀態陣列)
題解:主席樹,即針對每個詢問建一棵線段樹,但這樣會mle,不過我們可以發現由於相鄰線段樹的公共部分很多,可以充分利用,達到優化目的,同時每棵線段樹還是保留所有的葉節點只是較之前共用了很多共用節點。每次修改最多增加o(log n)的空間,所以總的空間複雜度是o(n log n)
c++ code:
#includeusing namespace std;const int maxn=20000100;
int root[1001000],lc[maxn],rc[maxn],val[maxn],cnt;
int n,m;
void build(int &rt,int l,int r)
int mid=l+r>>1;
build(lc[rt],l,mid);
build(rc[rt],mid+1,r);
}void add(int &rt,int ver,int l,int r,int x,int y)
int mid=l+r>>1;
if (x<=mid)add(lc[rt],lc[ver],l,mid,x,y);
else add(rc[rt],rc[ver],mid+1,r,x,y);
}void ask(int rt,int l,int r,int x)
int mid=l+r>>1;
if (x<=mid)ask(lc[rt],l,mid,x);
else ask(rc[rt],mid+1,r,x);
}int main()else
} return 0;
}
洛谷P3919 可持久化陣列
題目大意 需要維護乙個長度為 n 的陣列,支援在歷史版本上單點修改和單點查詢。題解 顯然,如果直接暴力維護的話會 mle。因此,採用線段樹進行維護,使得空間複雜度由 o mn 降至 o mlogn 不過相應的時間複雜度由 o 1 上公升至 o logn 如下 include using namesp...
洛谷P3919 模板 可持久化陣列 主席樹
題目連線 如題,你需要維護這樣的乙個長度為n n的陣列,支援如下幾種操作 在某個歷史版本上修改某乙個位置上的值 訪問某個歷史版本上的某一位置的值 此外,每進行一次操作 對於操作2,即為生成乙個完全一樣的版本,不作任何改動 就會生成乙個新的版本。版本編號即為當前操作的編號 從1開始編號,版本0表示初始...
洛谷P3919可持久化線段樹
有了可持久化陣列,便可以實現很多衍生的可持久化功能 例如 可持久化並查集 如題,你需要維護這樣的乙個長度為 n 的陣列,支援如下幾種操作 在某個歷史版本上修改某乙個位置上的值 訪問某個歷史版本上的某一位置的值 此外,每進行一次操作 對於操作2,即為生成乙個完全一樣的版本,不作任何改動 就會生成乙個新...