給定乙個長度為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...