51nod-1893 Travel-主席樹+hash
題意:
給出一張n個點,m條邊的無向圖,每個點有點權,求一條從1到n的路徑,使得經過的點中點權大的個數儘量少
n<=100000
Solution:
相當於求一條將這條路徑中的所有點權排序後,字典序最小的路徑
用主席樹維護當前路徑經過不同點權的次數,再運用hash可以在logn的時間內判斷兩個字串的大小
再加上堆優化的dij,複雜度為
程式碼:
#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