標籤:掃瞄線,樹狀陣列,單調棧
題目傳送門
給定長度為n的序列:a1,a2,…,an,記為a[1:n]。類似地,a[l:r](1<=l<=r<=n)是指序列:al,al+1,…,ar-1,ar。若1<=l<=s<=t<=r<=n,則稱a[s:t]是a[l:r]的子串行。現在有q個詢問,每個詢問給定兩個數l和r,1<=l<=r<=n,求a[l:r]的子串行的最小值之和。例如,給定序列5,2,4,1,3,詢問給定的兩個數為1和3,那麼a[1:3]有6個子序列a[1:1],a[2:2],a[3:3],a[1:2],a[2:3],a[1:3],這6個子序列的最小值之和為5+2+4+2+2+2=17。
輸入檔案的第一行包含兩個整數n和q,分別代表序列長度和詢問數。接下來一行,包含n個整數,以空格隔開,第i個整數為ai,即序列第i個元素的值。接下來q行,每行包含兩個整數l和r,代表一次詢問。
對於每次詢問,輸出一行,代表詢問的答案。
5 5
5 2 4 1 3
1 51 3
2 43 5
2 5
28
17 11
11 17
1 <=n,q <= 100000,|ai| <= 10^9
給出長度為n的序列和m次詢問
每次詢問給定兩個端點l,r
詢問l,r的子區間內最小值之和
莫隊+dp
列舉元素並計算貢獻
設left表示左邊第乙個比x小的值的位置
所以向右拓展時新增的(r+1)-l+1個區間中左端
點在le
ftr+
1+1−
>r+
1區間內
的價值都
是ai+
1 左端點
在lef
tr+1
+1
−>r+
1區間內
的價值都
是ai+
1現在的
問題就是
l−>le
ftr+
1區間的
貢獻了 現在的
問題就是
l−
>le
ftr+
1區間的
貢獻
了用dp
設f[i][j]表示i->j區間內所得到的貢獻f[
i][j
]=f[
i][l
eftj
]+(j
−lef
tj)∗
ajf [i
][j]
=f[i
][le
ftj]
+(j−
left
j)∗a
j發現可以消掉乙個維度f[
i]=f
[lef
ti]+
(i−l
efti
)∗ai
f [i
]=f[
left
i]+(
i−le
fti)
∗a
i然後查詢區間的時候取出f[r]-f[l-1]就好了
掃瞄線**吼!我用掃瞄線寫的,因為hnoi2017的影魔也是掃瞄線,感覺兩道題都是同乙個套路,我這題就用的這種寫法
預處理每個a[i]數作為最左的最小值向左右延伸到的位置le[i],ri[i],則l=le[i]..i,r=i..ri[i]的區間的最小值為a[i]
將(l,r)放到二維平面上去,那麼詢問轉化為求乙個矩形內部的和
然後就掃瞄線+樹狀陣列維護即可,常數較大
#include
#include
#include
#include
#include
#include
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#define mem(x,num) memset(x,num,sizeof x)
#define reg(x) for(int i=last[x];i;i=e[i].next)
using namespace std;
inline ll read()
while(ch>='0'&&ch<='9')
return
x*f;
}const int maxn=1e5+7;
int n,m,a[maxn],stack[maxn],top=0,le[maxn],ri[maxn],ep=0,p=0;
ll ans[maxn],ks[2][maxn],bs[2][maxn];
void modify(ll*f1,ll*f2,int
x,ll f)
inline ll query(ll*f1,ll*f2,int
x)struct ask
}qs[maxn];
struct node
}sq[maxn<<1];
inline bool operator < (node a,node b)
inline bool operator < (ask a,ask b)
int main()
while(top)ri[stack[top--]]=n;
dep(i,n,1)
while(top)le[stack[top--]]=1;
rep(i,1,n);
sq[ep++]=(node);
}sort(sq,sq+ep);
rep(i,0,m-1)qs[i].l=read(),qs[i].r=read(),qs[i].id=i;
sort(qs,qs+m);
rep(i,0,m-1)
rep(i,0,m-1)printf("%lld\n",ans[i]);
return
0;}
洛谷P3250 HNOI2016 網路
題目大意 給定一棵樹。有三種操作 0 u v t 在 u 到 v 的鏈上進行重要度為 t 的資料傳輸。1 x 結束第 x 個時刻的資料傳輸 保證合法 2 x 詢問不經過點 x 的資料傳輸中重要度最大的是多少 無解輸出 1 題解 可以發現一條路徑對所有不在這條路徑上的點有貢獻,所以可以把這些區間給排除...
洛谷 SDOI2016 遊戲
初見安 這裡是傳送門 洛谷p4069 sdoi2016 遊戲 這題真的是咕了好幾個月了終於過了,然後又咕了幾個星期才來寫部落格 題意很簡單,每次讓你在一條路徑上放乙個等差數列,問你某點上數的最小值。這就是乙個李超線段樹的模板題了。我們樹上利用樹剖開一棵線段樹,維護每一段等差序列的最小值就好。接下來看...
題解 HNOI 2016序列
collapse bzoj 這道題在hnoi2016中還算是好的了 這題中如若去掉多組詢問的話可以在o nlogn o n log n 的時間內得解 並查集 但多組詢問必定要優化,發現這種其他結構基本上無法涉足的題目就只能上莫隊了 我也不知道為啥想到莫隊,可能這就是題感吧 減去o nn o n n ...