zoukankan      html  css  js  c++  java
  • 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;
    }
    /*
    
    */
  • 相关阅读:
    rest webapi 返回数据
    下载指定路径的文件到本地服务器
    NPOI excel文件解析
    (Demo分享)利用JavaScript(JS)实现一个九宫格拖拽功能
    关于DOM的理解
    (Demo分享)利用JavaScript(JS)做一个可输入分钟的倒计时钟功能
    关于闭包函数和递归函数的详细理解
    纯CSS制作加<div>制作动画版哆啦A梦
    冒泡排序
    Python常用模块及正则表达式知识点,你需要了解的全在这了
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9187534.html
Copyright © 2011-2022 走看看