SCOI2016 萌萌噠 解題報告

2022-04-07 10:01:57 字數 1355 閱讀 3028

[scoi2016]萌萌噠

有乙個長度為 \(n\) 的大數,

有 \(m\) 個形如l1,r1,l2,r2的限制, 表示區間 \([l1,r1]\) 和 \([l2,r2]\) 完全相等,

求滿足這些限制的數的個數, 不能含有前導零.

\((1 \le n,m \le 10^5)\)

暴力 : 直接 \(o(nm)\) 把相等的數合成乙個並查集, 最後若並查集的數量為 \(k\), 則答案為 \(9 \times 10^\). (不能有前導零).

考慮優化.

首先想到線段樹優化連邊, 但是發現用線段樹的話, 無法確定區間的對應關係.

為了連邊之後依舊能確定區間的對應關係, 我們需要對每乙個點都有乙個以它為起點的儲存結構.

所以, 我們可以弄乙個類似於 st表 的東西, 但理解方式類似於 線段樹.

把整個序列分成 \(\log n\) 層, 每一層之間進行連邊.

在給定了l1,r1,l2,r2時, 用類似於st表查詢最值時的操作, 把 \([l1,r1]\) 和 \([l2,r2]\) 分別分成兩個長度為 \(2\) 的若干次方的區間, 然後在這幾個區間之間連邊.

在所有邊都連完後, 從上往下一層一層地把連邊下傳, 反映在**中其實就是並查集的合併.

需要注意的是, 在下傳的時候, 設當前層的兩個連線區間為 \(a,b\), 我們還需要考慮 \(a\) 和 \(b\) 的子區間, 即下一層的四個區間 \(a_1,a_2\) 和 \(b_1,b_2\) 的連線情況,

若 \(a_1,a_2\) 是相連的, 就把 \(fa[b_1],fa[b_2]\) 設為 \(fa[a_1]\),

否則, 就把 \(fa[a_1],fa[a_2]\) 設為 \(fa[b_1]\).

#include#define ll long long

using namespace std;

const int _=1e5+7;

const int l=20;

const ll mod=1e9+7;

int n,m,fa[_][l+7],log[_];

bool vis[_];

ll ans;

void init()

}int find(int i,int k)

void run()

else

}} int j=find(1,0);

ans=9;

for(int i=2;i<=n;i++)

if(i!=j&&find(i,0)==i)

ans=ans*10%mod;

}int main()

SCOI2016 萌萌噠 題解

題目大意看原題面。我們首先考慮,對於每個相等的數,我們用並查集將其並起來,那麼由於不能有前導0,令最後集合的個數為c cc,所以答案就是9 1 0c 1 9 times 10 9 10c 1,除了開頭不能選0,只有9中選擇方案外,其餘的每個數字都有10種選擇方案 只有一位數字的時候需要特判,因為此時...

SCOI2016 萌萌噠 並查集 倍增

傳送門 一開始是想賭一把,把節點乙個乙個的unite,然後懷著wa的心情wa了。然後又準備用離散去優化,然後又懷著wa的心情wa了。萬般無奈去查題解,發現竟然要使用倍增?倍增是啥,我多少年沒有用過了 複習了一波倍增,原來倍增也可以用在並查集上,我對並查集又有了新的理解,這個資料結構,好強啊!incl...

SCOI2016 萌萌噠 倍增 並查集

乙個長度為n的大數,用s1s2s3.sn表示,其中si表示數的第i位,s1是數的最高位,告訴你一些限制條件,每個條件表示為四個數,l1,r1,l2,r2,即兩個長度相同的區間,表示子串sl1sl1 1sl1 2.sr1與sl2sl2 1sl2 2.sr2完全相同。比如n 6時,某限制條件l1 1,r...