這道題應該是可以通過組合數直接計算的,但是我不會數學證明,所以就用了一種簡單粗暴的方式。 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在最小最大值之間,那麼一定可以從最小值最大值位置所構成的區間中得到。那麼根據單調性二分就可以了。每次二分出乙個位置用杜教篩計算一下。對於最大值最小值所在的位置可以打表啊。這道題以前做過乙個靜態的,就是樹在開始的...