NOI2017 整數 解題報告

2022-04-29 20:18:09 字數 1695 閱讀 7611

有一些比較簡單的\(\log^2n\)做法

比如暴力在動態開點線段樹上維護每個位置為\(0\)還是\(1\),我們發現涉及到某一位加上\(1\)或者減去\(1\)實際上對其他位的影響只有區間覆蓋,通過線段樹上二分可以得到區間覆蓋的位置,然後暴力區間覆蓋即可。

反正我這種菜雞大常數寫法只得到了68分..

考慮利用勢能,注意到如果同時改變加法和減法,勢能很容易被\(b\)搞掉

如果分開維護加法和減法,把位置上的\(1\)的個數當做勢能,可以發現,暴力修改是均攤\(o(n\log a)\)的

直接暴力維護兩個陣列\(plu\)和\(dec\)

考慮單點求值,因為保證了\(x\ge 0\)

所以我們發現只需要兩個條件就可以確定第\(k\)位的值,即

第\(k\)位的答案即為\(ans_1 \ xor \ ans_2\),這裡討論一下就可以得到了

考慮找到\(\le p\)位置的兩個陣列第乙個不同的位置,然後比較大小

乙個暴力的想法是,把每個不同的位置塞到set裡面去,然後每次在set裡面二分找一下位置,也是\(\log^2n\)的

考慮到每次修改的乙個長為\(\log a\)連續的區間(這裡實際上饒了乙個大圈子)

所以把區間每\(\log a\)分一塊,塊也是有勢能的,然後set裡面一次賽乙個塊就可以了

複雜度就乙個\(\log\)了

code:

#include #include #include #include #define ll long long

using std::min;

const int size=1<<21;

char ibuf[size],*is,*it;

//#define gc() (is==it?(it=(is=ibuf)+fread(ibuf,1,size,stdin),is==it?eof:*is++):*is++)

#define gc() getchar()

template void read(t &x)

const int n=1e6+10;

int n,t1,t2,t3;

int plu[n*30],dec[n*30],bel[n*30];

int edt[n],vis[n];

std::set s;

std::set ::iterator it;

int qry(int p)

p=bel[p];

it=s.upper_bound(p);

if(s.empty()||it==s.begin()) return 1;

--it;

p=(*it)*32;

while(plu[p]==dec[p]) --p;

if(plu[p]>dec[p]) return 1;

else return 0;

}int main()

for(int op,a,b,k,i=1;i<=n;i++)

plu[p]=1;}}

else

dec[p]=1;}}

for(int j=1;j<=edt[0];j++)

if(flag)

else

s.insert(edt[j]);

}} else

}return 0;

}

2019.5.31

NOI2017 遊戲 解題報告

d 這麼小,你考慮直接對 d 個東西暴力 列舉 x 為 a 或 b c 就不用了,因為 a,b 已經包含 c 了,剩下的就是個 2 sat 問題了 但是你發現有個情況是,在若 a 即 b 時,如果 b 被 ban 了,那麼 a 也要被 ban 我們記錄一下被 ban 的點,然後在球方案的時候判一下 ...

noi2017 整數 線段樹or模擬

orzyyb 題目大意 你需要維護乙個有 3 times 10 7 個二進位制位的數,有一種修改方式和一種詢問方式 對這個數加上 a times2 b 其中 a 10 9 b 3 times 10 7 保證需要維護的這個數始終非負 詢問這個數第k個二進位制位的值 總共有 10 6 次詢問 修改操作 ...

題解 NOI2017整數 線段樹

在人類智慧型的山巔,有著一台字長為10485761048576位 此數字與解題無關 的超級計算機,著名理論計算機科 學家p博士正用它進行各種研究。不幸的是,這天颱風切斷了電力系統,超級計算機 無法工作,而 p 博士明天就要交實驗結果了,只好求助於學過oi的你.p 博士將他的計算任務抽象為對乙個整數的...