對於每個詢問操作,輸出滿足條件的子區間數
3 1 2 3
3 0
1 1 2 06
4對於每個位置,考慮以這個位置開頭的子區間,最右能延伸到**,設為suf[i]。
為了維護這個,設乙個next[i]表示第i個位置之後的第乙個同顏色的位置再**
那麼suf[i]就是next[i]的字尾min
轉換成模型:對於給定序列,這個序列構成的單調棧的權值和(也可以是最大值,最小值等)
聽說這個模型是wc2013的樓房重建?
設find(i,j,p)表示在[i,j]區間後面加入乙個p之後的單調棧的權值和
在這題中,單調棧是單調上公升的
那麼對於區間的右半邊,求出最小值rmin 如果r
min<
p ,那麼p對左半邊區間沒有影響,答案是find(i,mid,rmin)+find(mid+1,j,p)
否則,右邊被完全彈出,答案是find(i,mid,p)+p*(j-m)
如果i=j,直接考慮這個點是否會被p彈掉,輸出p或本身值
但是這樣會超時
設fm[i,j]表示將[i,j]區間的右邊最小值加入左邊的權值和,即find(i,mid,rmin)
這樣在find的時候直接呼叫這個,是o(1)的,查詢次數是log的
在每次修改時維護這個fm,也是會修改log次
最終複雜度是o(
nlog
2n)
#include
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define n 501000
#define inf 1010580540
#define ll long long
using
namespace
std;
int a[n],n,b[n],nxt[n];
ll t[n],g[n],fm[n];
set c[n];
typedef
set :: iterator it;
ll find(ll v,ll x,ll y,ll p)
void ins(int v,int i,int j,int x,int y)
int m=(i+j)/2;
if(x<=m) ins(v*2,i,m,x,y);
else ins(v*2+1,m+1,j,x,y);
t[v]=t[v*2]+t[v*2+1];
g[v]=min(g[v*2],g[v*2+1]);
fm[v]=find(v*2,i,m,g[v*2+1]);
}int main()
else}}
WC2015 冬眠營滾粗記
wc2015 轉眼間就過去了,回想半年前我還是乙個無知的渣渣現在已經能參加冬令營了心裡真的有點小激動 先不論胸牌滾粗的結果,來講一下自己這幾天的經歷吧 day 0 早上起來才發現自己什麼都沒收qaq 路上堵車差點就要趕不上飛機了,第一次坐飛機還是好激動的說。到杭州後就一群人跑去西湖玩了,西湖的落日真...
WC模擬 優美的樹
眾所周知,樹是n 個節點n 1 條邊的結構,而所謂的優美的樹需要滿足如下條件 1.這是一棵有根二叉樹 2.非葉節點需有兩個兒子 3.不可以變換為k 左偏樹。所謂的k 左偏樹是指一棵有k 個葉子的樹,每個非葉節點的右兒子均為葉子且均有左兒子。所謂的變換指的是經過若干次如下兩種變換 1.刪去乙個節點的兩...
2017 1 18WC模擬總結
well,恩今天的表現還好,全場與jason並列第九,但是處於密集分數段,今天其實是想出了兩題的,但是由於第二題很晚才開始認真想,於是就沒打出來了。一開始以為是高斯消元,然後發現不可以之後,利用各種邏輯運算的二進位制下等同的加法和乘法,誤打誤撞的就想到關鍵點上了,於是發現這其實是個圖,有許多鏈和環,...