給定乙個長度為n的序列,根據上面的公式,求出f(l, r)。
仔細觀察後發現,當l==r時,答案是a[l],當l < r時,答案是a[l] % a[l + 1] %...%a[r]。假設乙個數x模乙個比它大的數,相當於沒有模,只有比x小的數才起到了取模的作用。那麼我們用線段樹維護區間最小值,每次查詢(l + 1, r)範圍內第乙個比x小的數的位置(x初始為a[l]),假設記為pos,如果pos != -1,那麼l = pos,x %= a[pos],如果pos == -1,說明後面就沒有比x小的數了,就不用了查詢了。
#include #include #include #include #include using namespace std;
typedef long long ll;
const int n = 1e5+10;
int n, m, a[n];
struct nodetr[n<<2];
void pushup(int m)
void build(int m, int l, int r)
int mid = (l + r) >> 1;
build(m<<1, l, mid);
build(m<<1|1, mid + 1, r);
pushup(m);
}int ask(int m, int l, int r, int w)
int mid = (tr[m].l + tr[m].r) >> 1;
if(l <= mid && tr[m<<1].val <= w)
if(r > mid && tr[m<<1|1].val <= w)
return ask(m<<1|1, l, r, w);
return -1;
}int main()
printf("%d\n", ans);
} }return 0;
}
線段樹維護區間01
g.小 w 開關燈 problem 4467 discussion description 晚上到家小 w 通過開關燈來保持自己神經的興奮以便清醒地理筆記。n n 2 n 100,000 2 n 100,000 盞燈被連續的編號為 1 n 1 n 剛回到家的時候,所有的燈都是關閉的。小w 通過 n ...
維護序列(線段樹維護區間乘 區間加)
給定乙個長度為n的原序列和模數mod,m個操作,a,b 區間乘c,a,b 區間加c,統計 a,b 的區間和。思路 線段樹維護的還是區間和,但是這裡我們需要用到兩個懶標記,乙個記錄加法,乙個記錄乘法,乘法懶標記下傳之後要重置為1而不是0。對於乙個乘法操作,他影響的是區間和還有這個區間的加法標記 乘法標...
線段樹 離散區間,單點維護區間
這道題當時用線段樹搞不行,用主席樹搞,也不行。當場自閉。其實當時想到離散,但是沒想到用單點維護線段樹的區間。你這樣想,無非就是2e6次詢問,最多1 e9被分成最多2e6區間,我們要求的位置,一定在這2e6點的右邊第乙個。那麼把這個點,以及這個點x以及x 1的點儲存下來。維護的時候,線段樹初始化所有的...