inline void 樹狀數組神奇感悟【霧

才發現掃描線能夠用樹狀數組搞... 致遠星患者c++

(另外根據這篇博文的內容怎麼愈來愈感受本身往 PJ 入門靠攏了...)git

還有一點,咱把樹狀數組當作線段樹來康的話其實一切都會很清晰,這個來張四合一的圖:數組

4->1

第一張就是隨處可見的 sb 樹狀數組剖析圖了優化

第二張咱把點補齊了一下,即每一個點下面全部層都賦值一份點,而後以第一張圖相似的規則連邊,同時某個點正下方的點也要向其連邊spa

第三張咱把點長補全了,看起來... 是否是很像線段樹了呢? 2333code

而後第四張圖寫了一下某個點 update 時的虛擬情況,某個點一直往上跑就好辣,至於 query 時,類比線段樹查詢 1~x 內的信息(也就是前綴信息嘛),把查詢點對應到這裏,不就變成了每次去掉一個 lowbit 嘛blog

這樣,對於受衆較少的 OI 齡較大但對於樹狀數組只是幾個模板的(指本身) OIer 們來講,這篇博文的價值大部分就已經完成了...get

那麼還有一小部分就是樹狀數組(在理解了以上內容以後),在掃描線中的應用 ...it

你可能已經在撓頭了??? 線段樹不是區間查詢搞的掃描線?? 何時樹狀數組也能來湊熱鬧了?入門

腦補一下,拆成兩個前綴和可不就是區間嘛, 但其實,樹狀數組不能艹掃描線 【霧 (就算能咱也不會啊 QwQ)

不過在這裏,還有一個另外一種狀況的(僞)掃描線能夠用樹狀數組優化二維前綴和來作

eg

詢問 單個矩陣 與 多個矩形(互不相交,劃重點) 的面積交之和 , 多組詢問 ,資瓷離線 ,要求複雜度一隻 log ,而且略略卡常(雖然說原題時限給了 10 S 就是了)

數據比較友好,不須要離散... (講道理可能 PJ 的同窗倒能一眼看出二維前綴和,而後想着用 BIT 優化??? 雖然說仍是很超綱就是了)

Code

真 tm 好打,明明用線段樹維護的話會是個碼農題的說,用了樹狀數組多在紙上比劃兩下就行了

//by Judge
#include<bits/stdc++.h>
#define ll long long
#define Rg register
#define pb push_back
#define P pair<int,int>
#define fi first
#define se second
#define fp(i,a,b) for(Rg int i(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(Rg int i(a),I=(b)-1;i>I;--i)
#define go(u) for(Rg int i=head[u],v=e[i].to;i;v=e[i=e[i].nxt].to)
#define open(S) freopen(S".in","r",stdin),freopen(S".out","w",stdout)
using namespace std;
const int M=2e6+3;
typedef ll arr[M];
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
inline int read(){ int x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
} char sr[1<<21],z[20];int CCF=-1,Z;
inline void Ot(){fwrite(sr,1,CCF+1,stdout),CCF=-1;}
inline void print(ll x,char chr='\n'){
    if(CCF>1<<20)Ot();if(x<0)sr[++CCF]=45,x=-x;
    while(z[++Z]=x%10+48,x/=10);
    while(sr[++CCF]=z[Z],--Z);sr[++CCF]=chr;
} int n,m,W,L; ll ans[M]; vector<P> ql[M],qr[M],op[M];
namespace BIT {
    arr f,fx,fy,fs;
#define lowbit(x) (x&-x)
    inline void add(int x,int l,int r,ll s,int v) { ++x;
        while(x<=L+1) f[x]+=v,fx[x]+=v*l,fy[x]+=v*r,fs[x]+=v*s,x+=lowbit(x);
    }
    inline ll ask(int x,int l,int r) { ll sx=0,sy=0,s=0,ct=0; ++x;
        while(x) ct+=f[x],sx+=fx[x],sy+=fy[x],s+=fs[x],x^=lowbit(x);
        return ct*l*r-l*sy-r*sx+s;
    }
} using namespace BIT;
signed main() { open("intersec"); int a,b,c,d;
    n=read(),m=read(),W=read(),L=read();
    fp(i,1,n) a=read(),b=read(),c=read(),d=read(),
        op[a].pb(P(b,1)),op[a].pb(P(d,-1)),op[c].pb(P(b,-1)),op[c].pb(P(d,1));
    fp(i,1,m) a=read(),b=read(),c=read(),d=read(),
        ql[a].pb(P(d,i)),qr[a].pb(P(b,i)),ql[c].pb(P(b,i)),qr[c].pb(P(d,i));
        
    fp(i,0,W) {
        for(auto x: qr[i]) ans[x.se]+=ask(x.fi,i,x.fi);
        for(auto x: ql[i]) ans[x.se]-=ask(x.fi,i,x.fi);
        for(auto x: op[i]) add(x.fi,i,x.fi,1ll*i*x.fi,x.se);
    } fp(i,1,m) print(ans[i],"\n "[i<m]); return Ot(),0;
}
相關文章
相關標籤/搜索