洛谷3246 HNOI2016 序列

2021-08-15 20:59:52 字數 2968 閱讀 1177

標籤:掃瞄線,樹狀陣列,單調棧

題目傳送門

給定長度為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 ...