2018.01.04 bzoj5291: [Bjoi2018]鏈上二次求和(線段樹)
阿新 • • 發佈:2019-01-08
傳送門
線段樹基礎題。
題意:給出一個序列,要求支援區間加,查詢序列中所有滿足區間長度在
之間的區間的權值之和(區間的權值即區間內所有數的和)。
想題
分鐘,寫題
分鐘,調題兩小時真
好玩
我們令
表示字首和,
表示字首和的字首和。
首先讀完題發現要求的是:
=
=
推到這裡發現用線段樹維護動態的
陣列即可。
考慮區間修改
對於
陣列的影響。
- ,無影響。
- ,那麼
- ,那麼
然後就可以分開更新了。
然而我碼完之後常數太大,
了2個小時,然後換了寫法才過。
程式碼:
#include<bits/stdc++.h>
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (l+r>>1)
#define ri register int
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<1)+(ans<<3)+(ch^48),ch=getchar();
return ans;
}
typedef long long ll;
const ll mod=1e9+7,N=2e5+5,inv=5e8+4;
int n,m;
ll a[N],s1[N],s2[N];
struct Node{ll l1,l2,l3,sum,a,b,c;}T[N<<2];
inline void pushup(int p){T[p].sum=(T[lc].sum+T[rc].sum)%mod;}
inline void pushnow(int p,ll a,ll b,ll c){
T[p].a+=a,T[p].b+=b,T[p].c+=c,(T[p].sum+=a*T[