[BZOJ4994][Usaco2017 Feb]Why Did the Cow Cross the Road III(树状数组)

越来越写不来简单题了。

就是求a[i]到b[i]之间的位置有多少个数是第一次出现且目前仅出现了一次。树状数组,每次给第一次出现的数的位置+1,若到了第二次出现的位置,则将第一次出现的位置-1即可。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 4 typedef long long ll;
 5 using namespace std;
 6 
 7 const int N=100010;
 8 int n,x,ans,p[N],c[N];
 9 
10 void add(int x,int k){ for (int i=x; i<=2*n; i+=i&-i) c[i]+=k; }
11 int que(int x){ int res=0; for (int i=x; i; i-=i&-i) res+=c[i]; return res; }
12 
13 int main(){
14     scanf("%d",&n);
15     rep(i,1,2*n){
16         scanf("%d",&x);
17         if (!p[x]) p[x]=i,add(i,1);
18         else add(p[x],-1),ans+=que(i)-que(p[x]);
19     }
20     printf("%d\n",ans);
21     return 0;
22 }

猜你喜欢

转载自www.cnblogs.com/HocRiser/p/10127504.html