【题解】洛谷P3660 [USACO17FEB]Why Did the Cow Cross the Road III

时间:2023-03-08 20:47:37

题目地址

又是一道奶牛题

从左到右扫描,树状数组维护【左端点出现而右端点未出现】的数字的个数。记录每个数字第一次出现的位置。

若是第二次出现,那么删除第一次的影响。

#include <cstdio>
#include <cstring>
#define re register
#define GC getchar()
#define Lowbit(X) (X&(-X))
#define Clean(X,K) memset(X,K,sizeof(X))
int Qread () {
int X = ; char C = GC ;
while (C > '' || C < '') C = GC ;
while (C >='' && C <='') {X = X * + C - '';C = GC ;}
return X ;
}
const int Maxn = << ;
int N , Vis[Maxn >> ] , A[Maxn] , Head[Maxn >> ] , T[Maxn];
unsigned long long int Ans = ;
int Ask (int X) {re int Ans = ;while (X > ) { Ans += T[X] ; X -= Lowbit(X) ;}return Ans ;}
void Add (int X , int K) {while (X <= N) {T[X] += K;X += Lowbit(X) ;}}
int main () {
N = Qread () * , Clean(Vis , ) ;
for (re int i = ;i <= N; ++ i) A[i] = Qread () ;
for (re int i = ;i <= N; ++ i)if (Vis[A[i]]) Add (Head[A[i]] , -) , Ans += Ask (i) - Ask (Head[A[i]]) ;
else Head[A[i]] = i , Add (i , ) , Vis[A[i]] = ;
printf ("%lld\n" , Ans) ;
fclose (stdin) ,fclose (stdout);
return ;
}