] 正著考慮是不太容易的,考慮其它對e[p_i]的貢獻。
1.設有j < i,aj
<=ai
就可以有貢獻ai
−aj+
1rj−
lj+1
。 2.設有j>i,aj
就可以有貢獻ai
−ajr
j−lj
+1
下列描述以1為準。
現在不具體考慮aj
的值,而是從大體上考慮,j對a的值取[lj
..rj
]的貢獻是乙個等差數列,對[rj
+1..max]的貢獻都是1.
於是打一棵動態權值線段樹來維護就好了。
2同理。
注意貢獻的意義是乙個數前面有多少個,而排名是從1開始算的,所以要加1.
code:
#include
#include
#define ll long long
#define fo(i, x, y) for(ll i = x; i <= y; i ++)
#define fd(i, x, y) for(ll i = x; i >= y; i --)
using
namespace
std;
const ll n = 100005, mo = 1e9 + 7;
const ll ni_2 = 5e8 + 4;
const ll m = 1e9;
ll n, ni[n];
ll s[n], l[n], r[n], ans[n];
struct tree t[10000000];
ll tot;
ll ksm(ll x, ll y)
return s;
}void add(ll i, ll x, ll s, ll tt)
void down(ll i, ll x, ll y)
void change(ll i, ll x, ll y, ll l, ll r, ll s, ll tt)
ll m = (x + y) / 2;
if(t[i].l == 0) t[i].l = ++ tot;
if(t[i].r == 0) t[i].r = ++ tot;
down(i, x, y);
if(r <= m) change(t[i].l, x, m, l, r, s, tt); else
if(l > m) change(t[i].r, m + 1, y, l, r, s, tt); else
change(t[i].l, x, m, l, m, s, tt), change(t[i].r, m + 1, y, m + 1, r, (s + tt * (m - l + 1)) % mo, tt);
t[i].w = (t[t[i].l].w + t[t[i].r].w) % mo;
}ll find(ll i, ll x, ll y, ll l, ll r)
int main()
memset(t, 0, sizeof(t));
tot = 1;
fd(i, n, 1)
ll as = 0;
fo(i, 1, n) as = (as + s[i] * ans[i] % mo) % mo;
printf("%lld", as);
}
NOIP2017模擬 鴨舌
題目 小美喜歡吃鴨舌。有乙個 n 個點的樹,每個節點 i 第 i 個點上有 ai 個鴨舌。小美一開始處於 x 號點。每次小美可以選擇乙個與現在的點有邊的點而且那個點還有鴨舌,那麼小美會走到那個點並吃乙個鴨舌。要保證小美最後還是走到 x 號點。問小美最多能吃幾個鴨舌?輸入格式 輸入第一行乙個整數 n ...
NOIP2017模擬 區間
2017.11.3 t1 2032 樣例資料 輸入3 2 1 2 1 1 2 4 5輸出 2 6分析 這道題為什麼要放在t1 考得我懷疑人生。本來也只會暴力找,對於30 的資料我是這樣的 先離散化,再二維陣列記錄所有顏色的在每個位置的字首和,然後四層迴圈暴力查詢。而正解是 先離散化,再把每種顏色的每...
NOIP2017模擬A組模擬8 5 序列問題
輸入檔名為seq.in。首先輸入n。接下來輸入n個數,描述序列 a。輸出檔名為seq.out。輸出一行乙個整數代表答案。7 0 35 40 45 56 65 94 對於30 的資料,n 5000 對於60 的資料,n 50000 對於100 的資料,n 500000,0 a i 10 9 這題還是很...