並不對勁的P5589

2022-05-08 20:00:13 字數 1435 閱讀 8547

題目大意

有\(n\)(\(n\leq 10^9\))個數:\(1,2,...,n\),每次操作是隨機取乙個沒被刪除的數\(x\),並刪去\(x,x^2,x^3,...\)。

求期望幾次刪完所有數。

題解可以把問題轉換成:有\(n\)個數,每次操作隨機取乙個數\(x\),若\(x\)未被標記則標記\(x,x^2,x^3,...\)並刪去\(x\),反之則刪去\(x\),求期望刪多少個未被標記的數。

發現乙個數\(x\)被計入答案的充要條件是\(\forall y\in\\)滿足\(\exists k,y^k=x\),刪除序列中\(y\)在\(x\)之後。

記\(y\)的個數為\(p\),問題變成有\(p+1\)個數的排列,指定的數在第乙個的概率。這個問題的答案是\(\frac\)。

也就是說,設\(p_i\)表示當\(x=i\)時\(y\)的個數,那麼原問題的答案是\(\sum\limits_^n \frac\)。

這個式子看上去只能\(\theta(n)\)地求。

發現\([2,n]\)中有\(\lfloor \sqrt n \rfloor-1\)個平方數,三次根號\(n\)下取整減1個立方數……,\(p_i\neq 0\)的數的個數很少,這些數可以暴力求。

\(p_i=0\)的數的\(\frac=1\),可以直接求。

**

#include#include#include#include#include#include#include#include#include#include#include#include#include#define rep(i,x,y) for(register int i=(x);i<=(y);++i)

#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)

#define view(u,k) for(int k=fir[u];~k;k=nxt[k])

#define ll long long

#define maxn 1000007

using namespace std;

int read()

void write(int x)

int f=0;char ch[20];

if(x<0)putchar('-'),x=-x;

while(x)ch[++f]=x%10+'0',x/=10;

while(f)putchar(ch[f--]);

putchar('\n');

return;

}int n,t,mx=1e9,pos[maxn],cnt;

mapmp;

ll mul(ll x,int y)return res;}

int main()

} t=read();

while(t--)

return 0;

}

一些感想

偉大的ysf口胡的

並不對勁的splay

splay和不加任何旋轉一定會被卡的二叉搜尋樹的唯一區別就是每次操作把當前節點旋轉到根。旋轉有各種zig zag的組合方式,感覺很麻煩,並不對勁的人並不想講。其實可以找出一些共性將它們合併。設ls a 點a是其父親的左兒子 son a 0 a的左兒子,son a 1 a的右兒子,fa a a的父親。...

並不對勁的費用流

最小費用最大流肯定要保證最大流,所以它和最大流有一些類似的性質。如果把費用看成邊,就可以每次走最短路 保證費用最小 走到不能走為止 保證最大流 費用流版的ek就是這樣。需要注意的是,反向弧的邊權為它對應的正向弧的費用的相反數,所以最短路要用spfa來求。費用流版的dinic,又叫zkw費用流,還是多...

並不對勁的字尾陣列

字尾陣列sa x 表示排序後第x位在排序前的位置。這個東西的求法有兩種,一種是倍增,時間複雜度o n log n 或o n log2n 另一種是用不知道什麼方法做到的o n 至於第二種方法是什麼,並不對勁的人並不知道,所以只說倍增。考慮正常地比較兩個字串,都是從頭比較到尾 那麼,如果把兩個字串都斷成...