顯然的結論是:超過$\sqrt n$的牌堆不會超過$\sqrt n$個。
所以可以分塊維護資訊:
對於牌數小於$\sqrt n$的,用乙個桶維護。
對於牌數大於$\sqrt n$的,用$vector$暴力插入刪除維護。
同時維護答案,為了做到$o(1)$修改,也用分塊進行維護。
值不同的數,位置一定是固定的。
所以可以只對值相同的數在類似歸併的過程中進行$dp$。
考慮每乙個值,設$dp_$表示這個值在原序列上出現的第$i$個副本,在歸併排序深度為$dep$的意義下排名為$j$的概率。
處理出陣列$g_$表示歸併排序過程中,兩個指標分別指向$i,j$的概率,
$f_$表示第$i$位轉移到第$j$位的概率,可以在遞推$g$陣列的同時簡單求出。
然後隨便轉移就完了。
考慮題中給出的限制$min+or-max-and$。
不妨分別提出其中的$min-max,or-and$。
可以列舉當前考慮的右端點。
那麼對於不同的左端點:
$or-and$只有$2*log max(a_i)$種不同的取值,
因為二進位制位分別對應只增不減,只減不增。
$min-max$隨著左端點不斷減小單調遞減。
那麼可以列舉每乙個不同的取值,這個可以用鍊錶簡單維護(其實用兩個陣列暴力重構就可以)。
二分求出符合要求的最靠左的位置就可以。
然而這樣做的複雜度是$o(nlog^2n)$的,其實有一些無用的狀態。
因為之要求最靠左的左端點,從左到右列舉左端點所在的區間,在第乙個可行區間二分更新答案後結束列舉就完了。
為了二分時$o(1)$查詢,可以使用st表維護。
然而剛剛學到了新的資料結構貓樹,而且還可以和$zkw$線段樹一起用,所以打起來就很帥。
1 #include2 #include3#define lch p<<1
4#define rch p<<1|1
5using
namespace
std;
6const
int n=1e6+50007;7
struct
nodesa[105],sb[105
];10
intn,k,bit,ca,cb;
11int a[n],mx[22][n],mn[22][n],lg[n],ans[n<<1
];12
void build(int p,int l,int r,int
dep)
22void dfs(int p,int l,int r,int
ans)
28int mid=l+r>>1;29
dfs(lch,l,mid,ans);
30 dfs(rch,mid+1
,r,ans);31}
32 inline int query_min(int l,int
r)37 inline int query_max(int l,int
r)42 inline void modify(int l,int r,int
val)47}
48 inline int read(register int x=0,register char ch=getchar(),register int f=0)53
intmain(); cb=0;63
for(int j=1;j<=ca;++j) if(j==ca||sa[j].and!=sa[j+1].and||sa[j].or!=sa[j+1].or) sb[++cb]=sa[j];
64for(int j=1;j<=cb;++j) sa[j]=sb[j];
65 ca=cb;
66int flag=0;67
for(int j=1;j<=ca&&!flag;++j)
68if(sa[j].or-sa[j].and+query_min(sa[j].pos,i)-query_max(sa[j].pos,i)>=k)
75 modify(l,i,i-l+1
);76 flag=1;77
}78}79 dfs(1,1,bit,-1
);80
return0;
81 }
NOIP模擬91 多校24
簽到題 然而我陣列開小直接變成暴力分。發現其實就是第一類斯特林數,然後 n 2 推就好了。感覺可以用 ntt 優化成 nlogn 但是好像並沒有什麼卵用 再說了,我也不會。include define int long long define ull unsigned long long defin...
Math NOIP2016提高A組模擬9 15
樣例輸入 3 5樣例輸出 一行答案。1一臉懵逼。打了個表找規律,然而腦子愚鈍沒有找到。30 暴力。時間o n3 70 仔細觀察發現,只要判斷d n 的奇偶性就行了。當d n 中n是完全平方數的時候,d n 就是奇數,道理應該很簡單。所以,我們只需要對於每乙個i找到有多少個j使得i j是完全平方數即可...
模擬17 題解
t1 a.入陣曲 60 演算法 維護一下某一列的從第一行到這一行和二維字首和 然後列舉上下左右邊界,o n 4 100 演算法 省掉左右邊界的列舉,改為從左向右掃一邊,記錄總和 k的餘數,並放入桶中,可以發現,如果這個值出現過,那說明這個位置的總和減去那個位置的差 即這個區間 是k的正倍數 t2又是...