1. 程式人生 > >51nod-1893 Travel-主席樹+hash

51nod-1893 Travel-主席樹+hash

傳送門

題意:

給出一張n個點,m條邊的無向圖,每個點有點權,求一條從1到n的路徑,使得經過的點中點權大的個數儘量少

n<=100000

Solution:

相當於求一條將這條路徑中的所有點權排序後,字典序最小的路徑

用主席樹維護當前路徑經過不同點權的次數,再運用hash可以在logn的時間內判斷兩個字串的大小

再加上堆優化的dij,複雜度為O((n+m)lognlogn)

程式碼:

#include<cstdio>
#include<iostream>
#include<queue>
#define ull unsigned long long
using namespace std; const int bas=1e6+3; const int N=100010; int n,m,sz,vis[N]; struct tree{ int l,r; ull v; }tr[20*N]; ull mi[N]; int a[N],rk[N],head[N],id[N],rt[N],size; struct edg{ int to,next; }e[10*N]; void add(int x,int y){size++;e[size].to=y;e[size].next=head[x];head[x]=size;} void modify(int
&nw,int l,int r,int pos) { int k=nw; nw=++sz;tr[nw]=tr[k]; if (l==r) {tr[nw].v++;return;} int mid=l+r>>1; if (pos<=mid) modify(tr[nw].l,l,mid,pos); else modify(tr[nw].r,mid+1,r,pos); tr[nw].v=tr[tr[nw].l].v*mi[r-mid]+tr[tr[nw].r].v; } bool cmp(int x,int y) { if
(tr[x].v==tr[y].v) return 0; int l=1,r=n; while (l<r) { int mid=l+r>>1; if (tr[tr[x].l].v==tr[tr[y].l].v) x=tr[x].r,y=tr[y].r,l=mid+1; else x=tr[x].l,y=tr[y].l,r=mid; } return tr[x].v<tr[y].v; } struct Q{ int x,y; friend bool operator <(Q a,Q b) { return !cmp(a.y,b.y); } }; priority_queue<Q> q; void print(int nw,int l,int r) { if (l==r) { for (int i=1;i<=tr[nw].v;i++) printf("%d ",id[l]); return; } int mid=l+r>>1; print(tr[nw].l,l,mid);print(tr[nw].r,mid+1,r); } int read() { int x=0; char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x; } int main() { n=read(),m=read(); mi[0]=1;for (int i=1;i<=n;i++) mi[i]=mi[i-1]*bas; for (int x,i=1;i<=n;i++) id[i]=read(),rk[id[i]]=i; for (int x,i=1;i<=n;i++) x=read(),a[i]=rk[x]; for (int x,y,i=1;i<=m;i++) x=read(),y=read(),add(x,y),add(y,x); q.push({1,rt[1]}); while (!q.empty()) { int x=q.top().x;q.pop(); if (vis[x]) continue; vis[x]=1; int nw=rt[x];modify(nw,1,n,a[x]); for (int i=head[x];i;i=e[i].next) { int y=e[i].to; if (rt[y]==0||cmp(nw,rt[y])) { rt[y]=nw; q.push({y,rt[y]}); } } } modify(rt[n],1,n,a[n]); print(rt[n],1,n); }

相關推薦

51nod-1893 Travel-主席+hash

傳送門 題意: 給出一張n個點,m條邊的無向圖,每個點有點權,求一條從1到n的路徑,使得經過的點中點權大的個數儘量少 n<=100000 Solution: 相當於求一條將這條路徑中的所有點權排序後,字典序最小的路徑 用主席樹維護當前路徑經

2018.10.16 NOIP模擬 長者(主席+hash

傳送門 考試的時候開始sb的以為需要可持久化trietrietrie樹,發現建樹時空都是O(n2)O(n^2)O(n2)的。 然後發現由於每次只從原來的字串改一個字元。 因此直接主席樹維護區間hashh

codeforces464E The Classic Problem -- 最短路+主席+Hash

題目大意: 求s到t的最短路,邊權為2xi,xi≤105。 程式碼: #include<iostream> #include<cstdio> #include<cstring> #include<alg

[最短路 主席 Hash] Codeforces 464E #265 (Div. 1) E. The Classic Problem

很棒的資料結構練習題 因為邊權太大了 我們不能直接儲存 我們用主席樹! 比較直接從高位到低位找第一個不同的位 可以Hash下 每次加法 我們找到這一位之後第一個0 那麼0變為1 0之前一連串1都變成0 這裡有個小trick可以不用打標記 我們先建一棵全

Codechef Aug2017 #Walks on the binary tree -- 主席+Hash

傳送門 每次答案增加的值就是 n - 之前出現的數與 X 的 LCP 最大值。 而與 X 的 LCP 最大的點在 dfs 序上與 X 的距離最近。而在滿二叉樹上 X 在 dfs 序上的位置就等於 X 。 於是可以用 set 維護所有出現過的點,加入 X 時

Codeforces 464E The Classic Problem (最短路 + 主席 + hash

The jks main hup def cmp rhs sign code 題意及思路 這個題加深了我對主席樹的理解,是個好題。每次更新某個點的距離時,是以之前對這個點的插入操作形成的線段樹為基礎,在O(logn)的時間中造出了一顆新的線段樹,相比直接創建n顆線段樹更省

[最短路 && 主席維護HASH] 51nod1863 Travel

傳送門 把一條路徑上的點值按排名順序排序,那麼路徑的優劣就是字典序。 相當於是求一條字典序最大的路徑。 最長路 然後就是老套路,用主席樹來維護hash,就可以在O(log)的時間裡比較兩個串的字典序,然後就套最短路就可以了 用對優化的DIJ複雜度就是O(

【BZOJ3207】花神的嘲諷計劃Ⅰ Hash+主席

題目 成了 output ons 情況 不出 clu truct cstring 【BZOJ3207】花神的嘲諷計劃Ⅰ Description 背景 花神是神,一大癖好就是嘲諷大J,舉例如下: “哎你傻不傻的!【hqz:大笨J】” &l

bzoj2588 -- 鏈剖分+主席

stat dfs strong pri 權值線段樹 iostream top pan splay 先將權值離散。 顯然可以對於每個結點建一棵權值線段樹存這個點到根結點的路徑上的點權,詢問時在線段樹上二分,但這樣時間是O(n2log2n)的。 然後想到用主席樹優化,時間復雜度

可持久化線段主席)模板

spa std nod d+ sin 整理 ostream pan int 比賽時候寫的,這裏整理到這裏 #include <iostream> #include <cstdio> #include <cstring> using

Codeforces Round #406 (Div. 2) E. Till I Collapse(主席)

esp type 個數 gif lan upd roo node .com 題目鏈接:Codeforces Round #406 (Div. 2) E. Till I Collapse 題意: 給你n個數,對於每一個k(1<=k<=n),劃分區間,每個區間只能有

BZOJ 3674 可持久化並查集加強版(主席變形)

als ret desc scan sync scanf ops 只需要 ica 3673: 可持久化並查集 by zky Time Limit: 5 Sec Memory Limit: 128 MB Submit: 2515 Solved: 1107 [

51nod 1806 wangyurzee的

memset fine sin ace efi res pri () 空間限制 基準時間限制:1 秒 空間限制:131072 KB wangyurzee有n個各不相同的節點,編號從1到n。wangyurzee想在它們之間連n-1條邊,從而使它們

【BZOJ4448】[Scoi2015]情報傳遞 主席+LCA

std [0 參與 tput rip 正整數 控制 i++ getchar() 【BZOJ4448】[Scoi2015]情報傳遞 Description 奈特公司是一個巨大的情報公司,它有著龐大的情報網絡。情報網絡中共有n名情報員。每名情報員能有若幹名(可能沒有)下

Educational Codeforces Round 22 E. Army Creation 主席 或 分塊

tor ron following time long different value comm member E. Army Creation As you might remember from our previous

BZOJ 2735: 世博會 主席+切比雪夫距離轉曼哈頓距離

區間第k大 輸出 data 小數點 -s put and text esc 2735: 世博會 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 124 Solved: 51[Submit][Status][Discuss]

Educational Codeforces Round 22 E. Army Creation(主席)

type sin -- cat clu 方法 cto hid 一個數 題目鏈接:Educational Codeforces Round 22 E. Army Creation 題意: 給你n個數和一個數k,然後有q個詢問. 每個詢問 有一個區間[l,r],問你這個區間內在

hdu 4348 To the moon(主席區間操作)

esp ace 標記 return ++i urn div acm str 題目鏈接:hdu 4348 To the moon 題意: 給你n個數,有m個操作。 1.給區間[l,r]的所有數+d,並且時間戳+1 2.詢問當前時間戳的區間和。 3.詢問過去時間戳t的區間和。

POJ 2104 K-th Number(主席

ber sca first n) 次數 example == scan sorted K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 5742

算法總結——主席(poj2104)

() key orm 關於 data 分享 ogr d+ put 題目: Description You are working for Macrohard company in data structures department. After failing your