update : 最後乙個點時間空間已經放大
標題即題意
有了可持久化陣列,便可以實現很多衍生的可持久化功能(例如:可持久化並查集)
如題,你需要維護這樣的乙個長度為 n n n 的陣列,支援如下幾種操作
在某個歷史版本上修改某乙個位置上的值
訪問某個歷史版本上的某一位置的值
此外,每進行一次操作(對於操作2,即為生成乙個完全一樣的版本,不作任何改動),就會生成乙個新的版本。版本編號即為當前操作的編號(從1開始編號,版本0表示初始狀態陣列)
輸入格式:
輸入的第一行包含兩個正整數 n,m n, m n,m, 分別表示陣列的長度和操作的個數。
第二行包含n n n個整數,依次為初始狀態下陣列各位的值(依次為 ai a_i ai,1≤i≤n 1 \leq i \leq n 1≤i≤n)。
接下來m m m行每行包含3或4個整數,代表兩種操作之一(i i i為基於的歷史版本號):
對於操作1,格式為vi 1 loci valuei v_i \ 1 \ _i \ _i vi1locivaluei,即為在版本vi v_i vi的基礎上,將 aloci a__i} aloci 修改為 valuei _i valuei
對於操作2,格式為vi 2 loci v_i \ 2 \ _i vi2loci,即訪問版本vi v_i vi中的 aloci a__i} aloci的值
輸出格式:
輸出包含若干行,依次為每個操作2的結果。
輸入樣例#1:
5 1059 46 14 87 41
0 2 1
0 1 1 14
0 1 1 57
0 1 1 88
4 2 4
0 2 5
0 2 4
4 2 1
2 2 2
1 1 5 91
輸出樣例#1:
598741
8788
46
1 #include2 #include3 #include4 #include5using
namespace
std;
6const
int n=1000000;7
struct
node
8s[n*20],*pos=s;
12 node *root[n+5
];13
int a[n+5],b[n+5],n,m,sz,rem[n+5
];14
void build(node* &rt,int l,int
r)15
21int mid=(l+r)/2
;22 build(rt->ch[0
],l,mid);
23 build(rt->ch[1],mid+1
,r);24}
25void insert(node* &rt,int l,int r,int k,int
w)26
35int mid=(l+r)/2;36
if (k<=mid) insert(rt->ch[0
],l,mid,k,w);
37else insert(rt->ch[1],mid+1
,r,k,w);38}
39int query(node* rt,int l,int r,int
k)40
46int
main()
47 54 build(root[0],1
,n);
55for (i=1;i<=m;i++)
5664
else
6570
}71 }
模板 可持久化陣列(可持久化線段樹 平衡樹)
update 最後乙個點時間空間已經放大 標題即題意 有了可持久化陣列,便可以實現很多衍生的可持久化功能 例如 可持久化並查集 如題,你需要維護這樣的乙個長度為 n n n 的陣列,支援如下幾種操作 在某個歷史版本上修改某乙個位置上的值 訪問某個歷史版本上的某一位置的值 此外,每進行一次操作 對於操...
可持久化線段樹(主席樹)及可持久化陣列
定義 可以訪問歷史版本的線段樹為可持久化線段樹 可持久化線段樹之所以可以訪問歷史版本,是因為巨集觀上看,它為每個版本維護了一棵樹。當然,如果真的對每個版本建一顆樹,時間空間複雜度都hold不住。所以建立i版本的樹時,如果某顆子樹相對於i 1版本沒有變化,就可以直接使其父親對應的指標指向i 1版本的這...
可持久化平衡樹
如題。大家都知道,用權值線段樹可以過普通平衡樹那道題,那麼對於可持久化普通平衡樹,我們是否也可以用主席樹來搞一搞呢。答案是肯定的。只需要動態開點就行了。其他的跟普通平衡樹那道題一模一樣。這裡需要注意一點,當 l 和 r 都是負數的時候,2 就會有問題,因為 5 2 2 而 5 1 3 所以除2會使 ...