• 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
    ", 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
    ", ans);
        return 0;
    }
    /*
    
    */
  • 相关阅读:
    Truck History(poj 1789)
    Highways poj 2485
    117. Populating Next Right Pointers in Each Node II
    116. Populating Next Right Pointers in Each Node
    115. Distinct Subsequences
    114. Flatten Binary Tree to Linked List
    113. Path Sum II
    109. Convert Sorted List to Binary Search Tree
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9187534.html
Copyright © 2020-2023  润新知