傳送門
懸線法
題目大意:
對於乙個長度為n的數列,找出乙個子區間,
使子區間內的最小值與子區間元素和的乘積最大,
要求在滿足舒適值最大的情況下最小化長度,
最小化長度的情況下最小化左端點序號。
本題中我們可以考慮列舉最小值,將每個位置的數a[i]當作最小值,並考慮從i向左右擴充套件,找到滿足
的盡可能向左右擴充套件的區間 。這樣本題就被轉化成了懸線法模型這個題最主要的還是要求出l[i]和r[i]
l[i]和r[i]代表的是如果i是最小值的話向左和向右延申的最大下標
例如
3:如果讓3做最小值的話,下標最左是1,最右也是1
1:如果讓1做最小值的話,下標最左可以達到1,最右可以達到6
,,,,,
#include #include#include
#include
using
namespace
std;
const
int n = 100010
;int
n, a[n], l[n], r[n];
long
long
sum[n];
long
long
ans;
intansl, ansr;
bool fir = 1
;int
main()
for (int i = 1; i <= n; i++)
while (a[l[i] - 1] >= a[i]) l[i] = l[l[i] - 1
];
for (int i = n; i >= 1; i--)
while (a[r[i] + 1] >= a[i]) r[i] = r[r[i] + 1
];
for (int i = 1; i <= n; i++)
printf(
"%lld\n%d %d\n
", ans, ansl, ansr);
} return0;
}
#include #include#include
#include
using
namespace
std;
//懸線法
/*對於乙個長度為n的數列,找出乙個子區間,
使子區間內的最小值與子區間元素和的乘積最大,
要求在滿足舒適值最大的情況下最小化長度,
最小化長度的情況下最小化左端點序號。
*/typedef
long
long
ll;const
int maxn = 100010
;int
l[maxn],r[maxn],a[maxn];
ll sum[maxn];
ll ans;
bool fir = 1
;int
ansl,ansr;
intmain()
for(int i=1;i<=n;i++)
for(int i=n;i>=1;i--)
for(int i=1;i<=n;i++)
}printf(
"%lld\n
",ans);
printf(
"%d %d\n
",ansl,ansr);}}
區間最大最小值 ST表
這是一道st表經典題 靜態區間最大值 請注意最大資料時限只有0.8s,資料強度不低,請務必保證你的每次查詢複雜度為 o 1 o 1 若使用更高時間複雜度演算法不保證能通過。如果您認為您的 時間複雜度正確但是 tle,可以嘗試使用快速讀入 inline int read while isdigit c...
ST表 (求區間最大 最小值)
st表的功能很簡單 它是解決rmq問題 區間最值問題 的一種強有力的工具 它可以做到o nlogn 預處理,o 1 是查詢最值 像線段樹是o logn 的查詢 st表是利用的是倍增的思想 拿最大值來說 我們用st i j 表示,從i位置開始的2 j個數中的最大值,例如st i 1 表示的是i位置和i...
線段樹求區間最大值和最小值(指標)
鏈結 include include using namespace std define max a,b a b?a b define min a,b al a s r b if a 1 b 不是葉子結點線段 return s void update linetree s,int a,int b ...