1. 程式人生 > >【模板】可持久化線段樹

【模板】可持久化線段樹

大神講解下終於理解了可持久化和區間第 K大數的關係。。。

終於理解了權值線段樹是什麼。。。

權值線段樹:

       例:

                     1 1 2 7 9 11

         一串數列,權值線段樹裡的  線段  指  有序數列  裡的  一段區間  。。。 

         一般統計的是  一個  (一個區間裡的數)  的出現次數。。。

          一次插入為一個歷史狀態。。。

      應用線段樹的結構穩定性(建好後結構不變。。。只有統計值在變。。。)

          應用字首和就可解決。。。

         例:poj 2104(裸題。。。)

#include<iostream>
#include<cstdio>
#include<algorithm>
#define MAXN 8000001
using namespace std;

int var[MAXN];
int ch[MAXN][2];
int size[MAXN];
int poi=0,pos=0;

int n,m;
int num[MAXN];
int rank[MAXN];

int half(int x)
{
  int l=1,r=pos,mid;
  while(l<=r)
  {
    mid=(l+r)>>1;
    if(rank[mid]==x)return mid;
    if(x<rank[mid])r=mid-1;
    else l=mid+1;
  }return 0;
}

int ask(int x,int y,int l,int r,int k)
{
  if(l==r)return l;
  int mid=(l+r)>>1;
  int t=size[ch[x][0]]-size[ch[y][0]];
  if(t>=k)return ask(ch[x][0],ch[y][0],l,mid,k);
  else return ask(ch[x][1],ch[y][1],mid+1,r,k-t);
}

void ins(int x,int y,int l,int r,int val)
{
  if(l==r)
  {
    size[x]=size[y]+1;
    return ;
  }
  int mid=(l+r)>>1;
  if(val<=mid)
  {
  	ch[x][0]=++poi;ch[x][1]=ch[y][1];
  	ins(ch[x][0],ch[y][0],l,mid,val);
  }
  else
  {
  	ch[x][1]=++poi;ch[x][0]=ch[y][0];
  	ins(ch[x][1],ch[y][1],mid+1,r,val);
  }
  size[x]=size[ch[x][0]]+size[ch[x][1]];
}

void build(int x,int l,int r)
{
  size[x]=0;
  if(l==r)return;
  int mid=(l+r)>>1;
  ch[x][0]=++poi;
  build(poi,l,mid);
  ch[x][1]=++poi;
  build(poi,mid+1,r);
}

void pre()
{
  scanf("%d%d",&n,&m);
  for(int i=1;i<=n;i++)
    scanf("%d",&num[i]),rank[i]=num[i];
  sort(rank+1,rank+n+1);
  for(int i=1;i<=n;i++)
    if(rank[i]!=rank[i-1])rank[++pos]=rank[i];
    
  var[0]=1;
  build(1,1,pos);
}

void work()
{
  int t;
  for(int i=1;i<=n;i++)
  {
    t=half(num[i]);
    var[i]=++poi;
    ins(var[i],var[i-1],1,pos,t);
  }
}

void query()
{
  int op,ed,k;
  for(int i=1;i<=m;i++)
  {
    scanf("%d%d%d",&op,&ed,&k);
    printf("%d\n",rank[ask(var[ed],var[op-1],1,pos,k)]);
  }
}

int main()
{
  pre();
  work();
  query();
	
  return 0;
}


相關推薦

模板持久化線段 1(主席

base math 一次 數據 mar 指定 das min 第k小 題目背景 這是個非常經典的主席樹入門題——靜態區間第K小 數據已經過加強,請使用主席樹。同時請註意常數優化 題目描述 如題,給定N個正整數構成的序列,將對於指定的閉區間

刷題洛谷 P3834 模板持久化線段 1(主席

!= tchar 這樣的 信息 reg har mem hair define 題目背景 這是個非常經典的主席樹入門題——靜態區間第K小 數據已經過加強,請使用主席樹。同時請註意常數優化 題目描述 如題,給定N個正整數構成的序列,將對於指定的閉區間查詢其區間內的第K小值。

P3834 模板持久化線段 1(主席

lose printf TE article 發現 AC 但是 || amp 題目背景 這是個非常經典的主席樹入門題——靜態區間第K小 數據已經過加強,請使用主席樹。同時請註意常數優化 題目描述 如題,給定N個正整數構成的序列,將對於

模板持久化線段 1(主席) 洛谷p3834

題目背景 這是個非常經典的主席樹入門題——靜態區間第K小 資料已經過加強,請使用主席樹。同時請注意常數優化 題目描述 如題,給定N個正整數構成的序列,將對於指定的閉區間查詢其區間內的第K小值。 輸入輸出格式 輸入格式:   第一行包含兩個正整數N、M,分

luoguP3834 模板持久化線段 1(主席

luoguP3834 【模板】可持久化線段樹 1(主席樹)   Time Limit: 1 Sec   Memory Limit: 256 MB Description    這是個非常經典的主席樹入門題——靜態區間第K小    資料已經過加強,請使用主席樹。同時請注意常數優化   如題

洛谷P3834 模板持久化線段 1 主席

Code: #include<cstdio> #include<algorithm> using namespace std; const int maxn = 20000000 + 4; int n,m, sumv[maxn], node_cnt, root[m

莫隊P3834 模板持久化線段 1(主席).md

大家好,我是個毒瘤,我非常喜歡暴力資料結構,於是我就用莫隊+分塊過了這個題 Solution 發現這個題靜態查詢資瓷離線,於是考慮莫隊。 在這裡簡單介紹一下莫隊: 將所有詢問離線後,對原序列分塊。按照左端點所在塊單調不降排序。當左端點所在塊相同時,按照右端點單調排序。 然後用頭尾指標指向當前的區間,

模板持久化線段

大神講解下終於理解了可持久化和區間第 K大數的關係。。。 終於理解了權值線段樹是什麼。。。 權值線段樹:        例:                      1 1 2 7 9 11          一串數列,權值線段樹裡的  線段  指  有序數列  裡

LuoguP3834 模板持久化線段 1(主席)|| 離散化

name node urn con upd i++ cstring get pro 題目:【模板】可持久化線段樹 1(主席樹) 不知道說啥。 1 #include<cstdio> 2 #include<cstring> 3 #include&

LGOJ P3834 模板持久化線段 1(主席

持久 else amp scan modify str 線段樹 unique return 代碼 #include <cstdio> #include <iostream> #include <algorithm> using names

Luogu P3834 模板持久化線段 1(主席

while iostream 可持久化線段樹 const str stream con urn pac 就是板子、、、 節點中維護的值,就是1-i之間這個區間內出現了數的次數(權值線段樹?霧)。然後當我們查詢的時候,就是利用到了前綴和的思想,拿左端點那棵樹和右端點一減~

洛谷 P3835 模板持久化平衡

正常 發生 using 我沒 持久化 pro 現在 class 小數 這個題也是可以用可持久化線段樹來解決的。 值域線段樹(也有的叫權值線段樹)可以用來維護一個可重集,並實現一些一般情況下平衡樹才能實現的事情。 如果用值來當做區間左右端點,每個葉子節點上存某個值出現的次數,

Luogu P3835 模板持久化平衡

P3835 【模板】可持久化平衡樹 題意 題目背景 本題為題目普通平衡樹的可持久化加強版。 題目描述 您需要寫一種資料結構(可參考題目標題),來維護一些數,其中需要提供以下操作(對於各個以往的歷史版本): 插入\(x\)數 刪除\(x\)數(若有多個相同的數,因只刪除一個,如果沒有請忽略

題解 P3835 模板持久化平衡

就是可持久化後的普通平衡樹嘛(逃 題目描述不寫了(懶了 這裡是題目 主要思路:FHQ Treap + 可持久化 普通FHQ Treap加上一點可持久化的東西如下:(打上註釋的程式碼是可持久化的特殊操作) inline int merge(int x, int y) { if(!x || !y

洛谷P3835 模板持久化平衡

題目背景 本題為題目 普通平衡樹 的可持久化加強版。 資料已經經過強化 感謝@Kelin 提供的一組hack資料 題目描述 您需要寫一種資料結構(可參考題目標題),來維護一些數,其中需要提供以下操作(對於各個以往的歷史版本): 插入x數 刪除x數(若有多個相同的

Luogu3835 模板持久化平衡(fhq-treap)

  fhq-treap,也即非旋treap,可以在不進行旋轉操作的前提下維護treap。由於不需要旋轉,可以對其可持久化。   fhq-treap的基本操作是merge和split,並且通過這兩個操作實現對treap的各項維護。   merge用來合併兩棵treap,且要求滿足其中一棵treap中的最小值

[Luogu 3919]模板持久化數組(持久化線段/平衡

ins eset blog sta -s ctime it is put tex Description 如題,你需要維護這樣的一個長度為 N 的數組,支持如下幾種操作 在某個歷史版本上修改某一個位置上的值 訪問某個歷史版本上的某一位置的值 此外,每

洛谷P3402 模板持久化並查集(持久化線段線段

std 樹節點 https case 深度 build eof spa 復雜度 orz TPLY 巨佬,題解講的挺好的。 這裏重點梳理一下思路,做一個小小的補充吧。 寫可持久化線段樹,葉子節點維護每個位置的fa,利用每次只更新一個節點的特性,每次插入\(logN\)個節點,

[解題報告]P3919 模板持久化數組(持久化線段/平衡

版本 持久化 完全 直接 n) ace 思路 efi mes 題目簡述 維護一個長度為N的數組,支持如下幾種操作: 在某個歷史版本上修改某一個位置上的值 訪問某個歷史版本上的某一位置的值 此外,每進行一次操作(對於操作2,即為生成一個完全一樣的版本,不作任何改動),就會

P3919 模板持久化數組(持久化線段/平衡

數組 const spa lse 建立 clu reset c++ 包含 題目描述 如題,你需要維護這樣的一個長度為 N 的數組,支持如下幾種操作 在某個歷史版本上修改某一個位置上的值 訪問某個歷史版本上的某一位置的值 此外,每進行一次操作