題目鏈結
給定乙個長度為 \(n\) 的序列 \(a\),和乙個區間 \([l, r]\)。
求多少連續子串行的權值和在區間內,即滿足 \(1 \le i \le j \le n\) 且滿足 \(l \le \sum_^ a[i] \le r\) 的方案數。
區間和,很容易想到用字首和轉換,這樣區間相關變成了兩個點。設 \(s\) 為 \(a\) 的字首和,那麼統計就變成了這樣。
統計 \(0 \le i < j \le n\) 中滿足 \(l \le s[j] - s[i] \le r\) 的方案數的。資料只有一組詢問,顯然是支援我們列舉一維,的不妨列舉 \(s[i]\),那麼轉化一下式子,就是滿足 \(l + s[i] \le s[j] \le r + s[i]\) 且 \(i < j\) 的 \(j\) 的數量。
這就是乙個顯然的二維偏序問題,做法就是:
單調修改、區間查詢這個操作我們再熟悉不過了。但是這次因為離散化會把值域資訊搞沒,所以不能離散化,只能動態開點線段樹。(後來想了一下好像也可以,把數值全部打進陣列離散化一下,所以寫了兩個版本)。
\(o(n\log_2 10^)\)
動態開點線段樹版
#include #include using namespace std;
typedef long long ll;
const int n = 100005;
int n, l, r, rt, idx;
struct t t[n * 30];
ll lt = 9e18, rt = -9e18;
ll s[n], ans = 0;
void inline pushup(int p)
void insert(int &p, ll l, ll r, ll x)
int query(int p, ll l, ll r, ll x, ll y)
int main()
for (int i = n; ~i; i--)
printf("%lld\n", ans);
return 0;
}
樹狀陣列版
#include #include #include using namespace std;
typedef long long ll;
const int n = 100005;
int n, l, r, tot, c[n];
ll s[n], d[n], ans = 0;
int inline get(ll x)
void inline add(int x)
int inline ask(int x)
int main()
printf("%lld\n", ans);
return 0;
}
BJOI2016 迴轉壽司
似乎沒有人打平衡樹的題解,那我就來水一發 我們將題目做乙個簡單的轉化 設 sum i sum a j 那麼答案就是 sum sum l leq sum i sum leq r 我們可以利用容斥的思想進行簡單是轉化 sum sum l leq sum i sum sum sum r sum i sum...
BJOI2016 迴轉壽司 題解
傳送門qaq 給定乙個長度為 n 的序列 a 給定邊界 l 和 r 求出滿足 l le sum limits r a i le r 的 l,r 的數量。簽到題,感覺紫題太高看它了,真實難度頂多綠題。考慮列舉 r 計算出所有滿足題意的 l 的數量。設 s 為 a 的字首和陣列,若 l le s r s...
JOISC 2016 Day 3 迴轉壽司
joisc 2016 day 3 迴轉壽司 這題我無力吐槽了.強烈譴責出題人用腳造資料 其實這題主要還是部分分啟發正解吧。看到有個 s i 1,t i n 的做法就是維護乙個堆就可以了,所以擴充套件下就是分塊,然後每個塊維護乙個堆。散塊暴力,大塊直接查。但是有個很坑爹的問題在於,對於整塊的部分我們沒...