D吃了一發,E沒做出來,結果剛好上紫w,不知道何時能上橙...
E Number of k-good subarrays
怪怪的題,一種trivial但沒想到的分治(?做法。拆成兩部分,只有一部分往下遞迴。
函式\(f(n,k)=(l,r,v)\)表示\([0,n-1]\)中左邊滿足條件的連續段長度為\(l\),右邊為\(r\),中間的貢獻為\(v\)。拆成兩段計算\(f(n,k)=f(hbit,k)+f((hbit->n),k)\)。後半段最高位為1,轉換為\(f(n-hbit,k-1)\)。對於前半段,討論最高位是0/1,\(f(2^n,k)=f(2^{n-1},k-1)+f(2^{n-1},k)\)。記搜
學了std的寫法
tii solve(int x,int k) {
if(k<0) return tii(0,0,0);
if(x==1) return tii(1,1,1);
int hbit=63-__builtin_clzll(x);
hbit=(1ll<<hbit);
if(hbit==x) {
hbit>>=1;
if(mp.find(mkp(x,k))!=mp.end()) return mp[mkp(x,k)];
}
tii L=solve(hbit,k),R=solve(x-hbit,k-1);
int Ll=get<0>(L),Lr=get<1>(L),Lv=get<2>(L);
int Rl=get<0>(R),Rr=get<1>(R),Rv=get<2>(R);
//auto [Ll,Lr,Lv]=L,[Rl,Rr,Rv]=R;
int rl=Ll,rr=Rr,rv=0;
if(Ll==hbit) rl=Ll+Rl;
if(Rr==x-hbit) rr=Lr+Rr;
rv=(mod*2+Rv+Lv-calc(Lr)-calc(Rl)+calc(Lr+Rl))%mod;
if((hbit<<1)==x) mp[mkp(x,k)]=tii(rl,rr,rv);
return tii(rl,rr,rv);
}
F Sorting Problem Again
考慮最長的有序前字尾,記為\((1,L),(R,n)\) 則\((L+1,R-1)\)一定要被包含。還有字首中大於\(MIN_{L+1}^n(a)\)的部分和字尾中小於前面最大值的部分。線段樹上二分。
修改要維護最長有序前字尾。可以轉化成維護\(a_i>a_{i+1}\)的位置,一次修改只改兩個地方,amazing。然後用set