計蒜客 百度科學家(困難)

2022-04-30 02:27:08 字數 1713 閱讀 5627

【題意】給定n個非負整數,最終需要選擇乙個數字集合。m次操作,修改乙個非負整數,或規定選擇第x個數字則必須選擇區間[l,r]內的數字。最終求非空數字集合的最小值。\(n,m \leq 10^5\)。

需要特別注意,被替換了的非負整數也是可以選擇的。每乙個非負整數都是本質不同的,區間[l,r]內的數字指的是當前情況下區間[l,r]內的數字。

【演算法】主席樹優化建圖+tarjan縮點

【題解】考慮樸素做法,每次規定點x向區間內的點連邊,修改就建新的點替換進序列,最後tarjan縮點後求出度為0的點權最小值。這樣邊數是\(o(nm)\)的。

因為向區間連邊很容易想到用主席樹優化。每次修改在原來的基礎上新增一條鏈,父親向兒子連邊。每次規定用當前最後乙個在位置x的點編號向區間連邊。

複雜度\(o(n \ \ log \ \ n)\)。

【注意】

1.每次新建鏈都需要向左右兒子連邊。不要連向0。

2.邊陣列開3倍。

3.有向圖的tarjan演算法不用判斷反向邊。

#include#include#define ll long long

using namespace std;

bool isdigit(char c)

int read()while(isdigit(c=getchar()));

return s*t;

}const int maxn=100010,n=1800010;

int dfn[n],low[n],st[n],dfsnum,cnt,tot,first[n],col[n],sz,v[maxn],top,n,m,rt,ou[n];

ll num[n];

struct edgee[n*3];//three

void ins(int u,int v)

struct treet[n];

void insert(int &x,int y,int l,int r,int k,int p)

int mid=(l+r)>>1;

if(k<=mid)insert(t[x].l,t[y].l,l,mid,k,p);

else insert(t[x].r,t[y].r,mid+1,r,k,p);

if(t[x].l)ins(x,t[x].l);if(t[x].r)ins(x,t[x].r);//0

}void tarjan(int x)

else if(!col[e[i].v])low[x]=min(low[x],dfn[e[i].v]);

} if(dfn[x]==low[x])

}void modify(int k,int l,int r,int l,int r,int x)

int main()

else

} for(int i=1;i<=sz;i++)if(!dfn[i])tarjan(i);

for(int i=1;i<=sz;i++)num[col[i]]+=t[i].s;//long long

for(int i=1;i<=tot;i++)if(col[e[i].u]!=col[e[i].v])ou[col[e[i].u]]++;

ll ans=1ll<<60;

for(int i=1;i<=cnt;i++)if(!ou[i]&&ans>num[i])ans=num[i];

printf("%lld",ans);

return 0;

}

2018計蒜之道初賽第一場 百度科學家(中等)

大科學家有乙個圖書館,所以放書的容量也隨之增加了,圖書館可以看成乙個長度為 nn n 的序列,一開始裡面放著 nn n 本書,每本書都記載了乙個特定元素的資訊,書中的元素各不相同。大科學家會先進行若干次研究,最後進行一次科學實驗,這次實驗需要選取一些元素放在一起來進行。每次研究,大科學家會從圖書館中...

前百度首席科學家張棟 36歲以前做到這8點再談夢想

工程師都喜歡做一些量化的東西,我就想量化一下今年有那些變化。在我32歲的時候我認為最大的樂趣就是能夠寫 寫很多的 這是 讓我 很高興的一件事情。就算你將來不一定做技術,你也有很多的 因為 能夠培養乙個人的邏輯思維能力。邏輯我覺得分好幾個層面,不僅僅是 邏輯,還有商業邏輯。如果你將來要創業的話,你需要...

計蒜客 1373 百錢買百雞 複雜度優化

百錢買百雞問題 公雞五文錢乙隻,母雞三文錢乙隻,小雞三隻一文錢,用 100100 文錢買 100100 隻雞,公雞 母雞 小雞各買多少只?本程式要求解的問題是 給定乙個正整數 nn,用 nn 文錢買 nn 隻雞,問公雞 母雞 小雞各買多少只?輸入格式 輸入乙個正整數 nn。輸出格式 如果有解,依次輸...