省隊集訓Round3 DAY6

2021-08-03 14:48:53 字數 2501 閱讀 7734

這道題應該是可以通過組合數直接計算的,但是我不會數學證明,所以就用了一種簡單粗暴的方式。 an

s=∑2

|ic(

n,i)

∗c(n

,n−i

) an

s=∑2

|ic(

n,i)

2 101

8 肯定不能直接列舉,如果要計算的話也需要用到lucas定理。觀察發現這題的模數比較小,所以從模數入手。

考慮lucas定理。 n=

a[0]

∗p0+

a[1]

∗p1+

a[2]

∗p2+

...

m=b[

0]∗p

0+b[

1]∗p

1+b[

2]∗p

2+..

. 對n,m進行p進製分解,那c(

n,m)

%p=c

(a[0

],b[

0])∗

c(a[

1],b

[1])

∗...

.%p

如果某一位a[

i]

i],那麼答案在模p意義下一定是0,也就是沒有貢獻,所以我們現在考慮計算出所有有貢獻的答案。

確定了a之後,我們就可以通過列舉計算每一位的選擇。因為i必須是偶數,所以我們可以進行數字dp. f[

i][0

/1] 表示確定了第i位後,m是偶數/奇數的總貢獻。

轉移過程直接看**吧。

可持久化trie

首先我們考慮如果只有異或操作該怎麼做。因為是對全域性取xor,所以我們可以把要異或的值記錄下來,每次查詢的時候考慮上異或值即可,不會對trie的形態造成影響。

然後考慮and,對於每一位分開考慮,如果是and 1的話沒有影響。關鍵就是and 0,會使所有數當前位的取值變成0。

or的話,如果是or 1,會使所有數當前位變成1。我們不妨對於每一位開乙個標記陣列,表示當前位是否全部相同以及值是多少。如果某一位在操作的過程中由值不全相同變成相同,那麼我們就重構可持久化trie,如果某一位全部相同,我們就把所有數同一放到左兒子,方便查詢。

因為每一位只有一次由不同變成相同的機會,所以重構的次數不會太多,最多只有30次。

注意異或的時候別忘了修改每一位的標記。

#include

#include

#include

#include

#include

#define n 100003

using

namespace

std;

int xornum,n,m,a[n],ch[n*20][2],size[n*20],pd[n],opt[n],root[n],sz;

void insert(int i,int x)

size[now]=size[pre]+1;

}int query(int i,int j,int x)

else }}

return ans;

}int main()

if (s[1]=='o')

}if (flag)

}if (s[2]=='n')

}if (flag)

}if (s[2]=='s') }}

省隊集訓Round2 DAY3

用splay維護權值有序。每次加入乙個人,貪心的選出前i 1個人中要求最小的vi 1,判斷能否滿足,如果能滿足就把這vi 1個人的權值 1,剩下的人不需要他們的支援,那麼都賦值成0,並且把這些點移動到平衡樹中0所在的位置 如果不能滿足就直接在平衡樹中加入乙個 1.要求每乙個時間每條邊只能有乙個人經過...

省隊集訓Round3 DAY4

講序列分成三部分,大根堆,緩衝區s,小根堆。任意時刻保證mid在緩衝區中,並且盡量保證大根堆和小根堆的大小盡量相等。均攤時間複雜度為o 首先打表發現sg函式的規律。1 p為奇數,從0開始sg值01迴圈 要統計區間的答案其實就是統計區間中sg值為1的數的個數。用線段樹維護區間中偶數 奇數的個數其實就是...

省隊集訓Round2 DAY2

首先字首和的變化一定是連續的。那麼對於每個區間,我們找到他最大值和最小值所在的位置,如果k在最小最大值之間,那麼一定可以從最小值最大值位置所構成的區間中得到。那麼根據單調性二分就可以了。每次二分出乙個位置用杜教篩計算一下。對於最大值最小值所在的位置可以打表啊。這道題以前做過乙個靜態的,就是樹在開始的...