題解 luogu P2068 【統計和】
阿新 • • 發佈:2018-12-02
小水題
話說rayment大佬噓寒問暖兩天,差點教會我怎麼用splay求區間和。這題我差點就下狠手使用splay了。
線段樹1的退化版,change區間變成了change一個數,延遲標記?不存在!
所以我們只需要簡單建一棵線段樹,然後輕鬆模擬就好了。建樹其實只需要將樹的區間搞出來,區間和由於初始值為0,所以根本不需要求。
#include <bits/stdc++.h> #define maxn 100010 using namespace std; struct segment_tree{ int l,r; int v; }t[4*maxn]; void build(int x,int l,int r){ t[x].l=l;t[x].r=r; t[x].v=0;//因為初始值是0,所以建樹不需要那麼麻煩 int mid=(l+r)/2; if (l==r)return ; build(x*2,l,mid); build(x*2+1,mid+1,r);//建樹 } int y,z; void change(int x,int l,int r){ int mid=(l+r)/2; t[x].v+=z;//只改變一個值,所以每個包含只需要加一遍 if (l==r)return ; if (mid>=y)change(x*2,l,mid); else change(x*2+1,mid+1,r); } int ask(int x,int l,int r){ if (l<=t[x].l&&r>=t[x].r)return t[x].v;//如果完全包含,則直接返回 int mid=(t[x].l+t[x].r)/2; int v=0; if (l<=mid) v+=ask(x*2,l,r); if (r>mid) v+=ask(x*2+1,l,r);//遞迴 return v;//詢問區間和 } int main(){ int i,j,n,m; cin>>n; build(1,1,n); cin>>m; for (i=1;i<=m;i++){ char x; cin>>x>>y>>z; if (x=='x')change(1,1,n); else cout<<ask(1,y,z)<<endl; } return 0; }//主函式部分,沒什麼意義
線段樹板子題,剛學線段樹的oier也可以直接切了,加點經驗。