有一些比較簡單的\(\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 博士將他的計算任務抽象為對乙個整數的...