SCOI2016 萌萌噠 倍增 並查集

2022-07-13 20:39:25 字數 1210 閱讀 7638

乙個長度為n的大數,用s1s2s3...sn表示,其中si表示數的第i位,s1是數的最高位,告訴你一些限制條件,每個條件表示為四個數,l1,r1,l2,r2,即兩個長度相同的區間,表示子串sl1sl1+1sl1+2...sr1與sl2sl2+1sl2+2...sr2完全相同。比如n=6時,某限制條件l1=1,r1=3,l2=4,r2=6,那麼123123,351351均滿足條件,但是12012,131141不滿足條件,前者數的長度不為6,後者第二位與第五位不同。問滿足以上所有條件的數有多少個。

solution

漲姿勢了。

不難想到用並查集維護數字之間的相等關係,最後用聯通塊個數統計答案。

但這樣的複雜度是n^2的,需要去優化它,

考慮到每次合併都是兩段等長的區間進行合併,所以我們考慮使用倍增。

我們開nlogn個並查集,num[i][j]表示從i開始的2^j個數,每次區間合併我們把它拆成logn個區間分別合併。

最後自頂向底合併兒子,就像線段樹一樣,

code

#include#include

#define n 100002

using

namespace

std;

typedef

long

long

ll;const

int mod=1e9+7

;int num[n][20],f[n*20],n,m,tot,son[n*20][2

],l1,r1,l2,r2;

int find(int x)

long

long power(ll x,int

y)

return

ans;

}int

main()

}for(int i=1;i<=m;++i)

} for(int i=19;i>=0;--i)

for(int j=1;j+(1

<1

<=n;++j)

}int ans=0

;

for(int i=1;i<=n;++i)if(find(num[i][0])==num[i][0])ans++;

printf(

"%lld

",9*power(10,ans-1)%mod);

return0;

}

SCOI2016 萌萌噠 並查集 倍增

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

SCOI2016 萌萌噠 題解

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

SCOI2016 萌萌噠 解題報告

scoi2016 萌萌噠 有乙個長度為 n 的大數,有 m 個形如l1,r1,l2,r2的限制,表示區間 l1,r1 和 l2,r2 完全相等,求滿足這些限制的數的個數,不能含有前導零.1 le n,m le 10 5 暴力 直接 o nm 把相等的數合成乙個並查集,最後若並查集的數量為 k 則答案...