給出乙個長度為n的序列a,對於乙個m,定義該序列的價值為a[1]到a[m]的最大值+a[2]到a[m+1]的最大值+…+a[n-m+1]到a[n]的最大值。求當m取[1,n]時對應的價值。 n≤
106n ≤10
6考慮每個元素對答案的貢獻。當取最大值時,我們把權值看做第一關鍵字,下標看做第二關鍵字,這樣每個子串行就唯一對應乙個最大值。
對於每個元素,我們找到它左邊和右邊第乙個比它大的元素的位置,那麼當這個元素做貢獻時,對應的子串行就不能跨過比它大的元素。
設這個元素可以作貢獻的區間長度為len,那麼它對ans的貢獻係數必然是形如1 2 3 3 3 3 2 1的數列,只要用二階差分統計下就好了。
#include
#include
#include
#include
#include
const
int n=1000005;
const
int mod=998244353;
const
int inf=2000000000;
int n,a[n],stack[n],lef[n],rig[n],ans[n];
int read()
while (ch>='0'&&ch<='9')
return x*f;
}void mod(int &x)
void pre()
top=0;stack[++top]=n+1;
for (int i=n;i>=1;i--)
}int main()
for (int i=2;i<=n;i++) mod(ans[i]+=ans[i-1]);
for (int i=2;i<=n;i++) mod(ans[i]+=ans[i-1]);
int w=0;
for (int i=1;i<=n;i++) w^=ans[i];
printf("%d",w);
return
0;}
線段樹 單調棧 UNR 1 爭奪聖杯
用單調棧求出left right 可以發現每個點的貢獻是關於left right的分段函式 然後就是分段函式累加求和 當時打的線段樹 看了題解漲姿勢了 可以差分 做到o n include include includeusing namespace std typedef pairabcd typ...
UOJ 218 UNR 1 火車管理
維護一顆主席樹 火車入棧相當於區間修改,彈棧相當於返回歷史版本 維護線段樹區間求和 ps 之前沒把 放上來 extra的最後乙個點re,orz蒟蒻無能為力 include include include include include const int maxn 600005 const int ...
UOJ 218 UNR 1 火車管理
注意記憶體有些卡,有一些技巧 1.首先對於查詢的線段樹是全域性的,不需要動態開點 2.對於線段樹中的乙個節點 x 如果它的左右兒子都沒有兒子,那麼下一次做區間覆蓋時,就不需要對 x 新建兩個節點 include define lo o 1 define ro o 1 1 using namespac...