BZOJ4994 [Usaco2017 Feb]Why Did the Cow Cross the Road III 樹狀數組
阿新 • • 發佈:2017-08-24
lin size ros spa 題意 lld get html 統計
歡迎訪問~原文出處——博客園-zhouzhendong
去博客園看該題解
題目傳送門 - BZOJ4994
題意概括
給定長度為2N的序列,1~N各處現過2次,i第一次出現位置記為ai,第二次記為bi,求滿足ai<aj<bi<bj的對數。
n<=100000(這個數據範圍是我湊出來的,但是我沒試過更小的範圍,BZOJ上沒寫數據範圍(截止2017-08-24))
題解
水題,開一個樹狀數組在線解決。
比如我們順著掃過去,當到達一個 bj 時,我們求滿足條件的 ai,bi 個數,其實就是求 bi~bj 之間有幾個數出現一次而且是第一次出現。
所以我們開樹狀數組維護。
我順著做過去,對於每一個數字i,在ai的地方+1,到了bi就在ai的地方-1,並統計區間ans,累加即可。
代碼
#include <cstring> #include <cstdio> #include <algorithm> #include <cstdlib> #include <cmath> using namespace std; typedef long long LL; const int N=100000+5; int n,c[N*2],f[N]; LL ans=0; int lowbit(int x){ return x&-x; } void add(int x,int d){ for (;x<=n*2;x+=lowbit(x)) c[x]+=d; } int sum(int x){ int ans=0; for (;x>0;x-=lowbit(x)) ans+=c[x]; return ans; } int main(){ scanf("%d",&n); memset(c,0,sizeof c); memset(f,0,sizeof f); for (int i=1,x;i<=n*2;i++){ scanf("%d",&x); if (!f[x]){ f[x]=i; add(i,1); } else { ans+=sum(i-1)-sum(f[x]); add(f[x],-1); } } printf("%lld",ans); return 0; }
BZOJ4994 [Usaco2017 Feb]Why Did the Cow Cross the Road III 樹狀數組