JZ雅禮聯考 Binary 題解

2021-07-16 20:31:04 字數 1442 閱讀 2377

給定乙個長度為n的整數數列a和q次操作:

修改操作:形如 1 x y,表示將ax

的值修改為y;

詢問操作:形如 2 x y,表示詢問∑n

1(ai

+x)a

ndy 的值。 n,

q<=105

0<=ai

,x,y

<=220

題目怎麼說怎麼做。

二進位制總共只有20位,直接記錄每一位為1的有多少個數,假設記為cnt[i]查詢時,y的第i個二進位制位為1,就答案加上2i

∗cnt

[i] 。

我們還是對於每個二進位制位單獨考慮,且y這一位為1才考慮。

不考慮+x時,我們還可以弄一棵值域線段樹,那麼cnt[i]所包含的數就是這樣的:比i高的位任意,i位以內滿足在[2

i−1,

2i−1

] 這個區間內。可以發現我們查詢的區間對於整個值域來說並不連續,而是一段一段的,因此我們對每個二進位制位都開一棵值域線段樹,第i位的線段樹儲存的數則由ai

變為ai

mod2

i 。這樣我們操作第i位時,直接在第i位的線段樹中查詢[2

i−1,

2i−1

] 內的數有多少個,就行了。

接下來考慮+x。這個實際上是對查詢區間的位移,比如當前查詢區間[2

i−1,

2i−1

] ,那麼就變成[2

i−1−

x,2i

−1−x

] 。要注意這裡的x是mo

d2i 的。唯一的問題就是區間左端點可能為負。這好辦,先把0到右端點的正常操作,假設左端點變成了−z

,那我們再查詢[2

i−z,

2i−1

] 就行了。這裡相當於是退位一樣的東西。

//我把線段樹換成樹狀陣列,這樣常數小**短

#include

#define fo(i,a,b) for(int i=a;i<=b;i++)

using namespace std;

typedef long long ll;

const int maxn=(1e5)+5, mx=20, maxc=(1

<<20)+5;

int n,a[maxn],er[mx+5];

int c[mx+2][maxc];

int lowbit(int

x) void xg(int ty,int

x,int z)

for(; x

x+=lowbit(x)) c[ty][x]+=z;

}int get(int ty,int

x)int

q;int main()

while (q--)

else

else

}printf("%lld\n",ans);}}

}

雅禮聯考DAY2總結

成功被flag。並沒有翻盤。了。又是60分,mdzz。其實我今天不是很懂怎麼回事。第一題被卡log丟了40分,第二題被卡空間掉了50分,生無可戀。day1也是。t2網路掛了丟了100分,t3開小了掛了40分。如果網路正常。如果我空間開的正常點,不要老想著多水分。我就是高一第7了。感覺以前太浪,什麼做...

雅禮聯考DAY02 Path

給定乙個 n m 的網格,你在左下角 n,1 你只能往前走或者右拐,障礙和走過的點不能走。求走到 y,x 的方案數 mod k 的值。n,m 100,k 10 9.考慮當前走到了乙個點,剩下的能走的範圍是乙個矩形。於是倒著dp,設fp x1,y1,x 2,y2 f p,x1,y 1,x2 y 2表示...

JZOJ4015 雅禮聯考DAY01 數列

題目的意思很明確,看看資料範圍就覺得有點神奇,先看前面7個資料,這個就直接模擬就好了。在看8 14,此時的模數比較小,就知道應該是找迴圈節。然後就只剩下最後的了,有個特殊條件,看看怎樣利用,利用一下費馬小定理,就愉快地解決了這題。include include define ll long long...