藍橋 log大俠

2022-03-16 16:57:32 字數 1866 閱讀 5027

atm參加了速算訓練班,經過刻苦修煉,對以2為底的對數算得飛快,人稱log大俠。

一天,log大俠的好友 drd 有一些整數序列需要變換,log大俠正好施展法力...

變換的規則是: 對其某個子串行的每個整數變為: [log_2 (x) + 1] 其中 表示向下取整,就是對每個數字求以2為底的對數,然後取下整。

例如對序列 3 4 2 操作一次後,這個序列會變成 2 3 2。

drd需要知道,每次這樣操作後,序列的和是多少。

【輸入格式】

第一行兩個正整數 n m 。

第二行 n 個數,表示整數序列,都是正數。

接下來 m 行,每行兩個數 l r 表示 atm 這次操作的是區間 [l, r],數列序號從1開始。

【輸出格式】

輸出 m 行,依次表示 atm 每做完乙個操作後,整個序列的和。

這題暴力肯定可以得一部分的,區間大小最差的情況就是每次都給l=1,r=n,這時暴力肯定不行的,會寫線段樹的話,可以看出這題也就是單點更新以及總區間查詢。而它沒說資料範圍,但就算是1e18的話,取log對於每個位置的數來說,它最多也就更新個60次左右,所以我們可以加個標記,代表這個區間內還有沒有位置需要更新,然後再線段樹維護,時間複雜度就是60*nlog(n)這樣。

1 #include2 #include3

#define l(x) (x<<1)

4#define r(x) (x<<1|1)

5#define m(x) ((t[x].l+t[x].r)>>1)

6 typedef long

long

ll;7

const

int n=100118;8

struct

treet[n<<2

];13

ll a[n];

14void built(int id,int l,int

r)15

26built(l(id),l,m(id));

27 built(r(id),m(id)+1

,r);

28 t[id].flag=t[l(id)].flag|t[r(id)].flag;

29 t[id].sum=t[l(id)].sum+t[r(id)].sum;30}

31void modify(int id,int l,int

r)32

41if(l<=m(id))

42modify(l(id),l,r);

43if(r>m(id))

44modify(r(id),l,r);

45 t[id].flag=t[l(id)].flag|t[r(id)].flag;

46 t[id].sum=t[l(id)].sum+t[r(id)].sum;47}

48int

main()

4961

return0;

62 }

線段樹下線段果

不懂線段樹的話,知道stl的map的話,還有種map的寫法,思路一樣,當某個位置的值<=2時就把它從map刪去。

1 #include2 #include3 #include4

using

namespace

std;

5 typedef long

long

ll;6 mapmmp;

7 map::iterator b,e,temp;

8int

main()918

while(m--)

1933 printf("

%lld\n

",sum);34}

35return0;

36 }

stlwd

歷屆試題 log大俠

atm參加了速算訓練班,經過刻苦修煉,對以2為底的對數算得飛快,人稱log大俠。一天,log大俠的好友 drd 有一些整數序列需要變換,log大俠正好施展法力.變換的規則是 對其某個子串行的每個整數變為 log 2 x 1 其中 表示向下取整,就是對每個數字求以2為底的對數,然後取下整。例如對序列 ...

第五屆藍橋杯(國賽) Log大俠

問題描述 atm 參加了速算訓練班,經過刻苦修煉,對以 2 為底的對數算得飛快,人稱 log 大俠。一天,log 大俠的好友 drd 有一些整數序列需要變換,log 大俠正好施展法力 變換的規則是 對其某個子串行的每個整數變為 log2 x 1 其中 表示向下取整 就是對每個數字求以 2 為底的對數...

哪位大俠幫我看看

最近做乙個東西,就拿圖書管理打個比方吧。工具為 vc 資料庫為sql server,表一中放的是 借書的日期 以及 借多長時間 表二中放的是 提前多少天發郵件通知 表三中放的是 郵件接受人的郵箱位址 現在想做的功能 就是 1.在還書日期提前x天給借書人發郵件提醒 還書 2.同時給管理員發訊息,該給誰...