bzoj 1106
思路:很容易就能想到统计没两对点之间的未匹配点的个数。 在想怎么用数据结构维护这个东西,
没有想到用树状数组能很巧妙地维护出来, 就写了个莫队。。。
莫队:暴力维护就好了。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int,int> #define piii pair<int, pair<int,int> > using namespace std; const int N = 1e5 + 10; const int M = 10 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-6; const int B = 223; int n, a[N], cnt[N], l, r, ret; struct Qus { int l, r; bool operator < (const Qus &rhs) const { if(l / 233 == rhs.l / 233) return r < rhs.r; return l / 233 < rhs.l / 233; } } qus[N]; inline void update(int x) { ret += cnt[a[x]] ? -1 : 1; cnt[a[x]] ^= 1; } int main() { scanf("%d", &n); n <<= 1; for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); if(qus[a[i]].l) qus[a[i]].r = i - 1; else qus[a[i]].l = i + 1; } sort(qus + 1, qus + 1 + n / 2); l = 1, r = 0, ret = 0; LL ans = 0; for(int i = 1; i <= n / 2; i++) { int L = qus[i].l, R = qus[i].r; if(L > R) continue; while(r < R) update(++r); while(l > L) update(--l); while(r > R) update(r--); while(l < L) update(l++); ans += ret; } printf("%lld\n", ans / 2); return 0; } /* */
树状数组:
对于第一次遇到的数a[ i ], 我们往 i 位置加1, 对于第二次遇到的数,我们往 pre[ a[ i ] ] 位置减1,然后统计区间( pre[ a[ i ] ], i )的值加到答案中。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int,int> #define piii pair<int, pair<int,int> > using namespace std; const int N = 1e5 + 10; const int M = 10 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-6; int n, a[N], pre[N]; void modify(int x, int v) { for(int i = x; i < N; i += i & -i) a[i] += v; } int query(int x) { int ans = 0; for(int i = x; i; i -= i & -i) ans += a[i]; return ans; } int main() { scanf("%d", &n); LL ans = 0; for(int i = 1; i <= 2 * n; i++) { int x; scanf("%d", &x); if(!pre[x]) { pre[x] = i; modify(i, 1); } else { modify(pre[x], -1); ans += query(i) - query(pre[x]); } } printf("%lld\n", ans); return 0; } /* */