zoukankan      html  css  js  c++  java
  • 【BZOJ2120】数颜色(树套树+set)

    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2120

    题解:http://blog.sina.com.cn/s/blog_6e63f59e0101bm87.html

    一开始懒得离散化,跑了7000+ms23333 宛如一个智障,可是出现了这么迷醉的情况、

    2333果然还是要勤快一点 写个离散化啊

    #include <set>
    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define MaxN 20010
    #define MaxM 7000010
    using namespace std;
    int n, S = 0, m, tot = 0, N = 0;
    int num[MaxN], da[MaxN], map[MaxN];
    int root[MaxN], t1[MaxN], t2[MaxN];
    int ls[MaxM], rs[MaxM], sum[MaxM];
    char s[10];
    set <int> q[MaxN];
    struct rec{
        int l, r;
        char s[10];
    }op[MaxN];
    void Read_Data(){
        scanf("%d%d", &n, &m);
        for (int i = 0; i < MaxN; i++) q[i].insert(n+1), q[i].insert(0);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &num[i]);
            da[++tot] = num[i];
        }
        for (int i = 1; i <= m; i++){
            scanf("%s%d%d", op[i].s, &op[i].l, &op[i].r);
            if (op[i].s[0] != 'Q') da[++tot] = op[i].r;
        }
        sort(da+1, da+1+tot);
        map[++N] = da[1];
        for (int i = 2; i <= tot; i++)
            if (da[i] != da[i-1]) map[++N] = da[i];
    }
    
    int find(int x){
        int l = 1, r = N, mid;
        while (l < r) {
            mid = (l+r) >> 1;
            if (x <= map[mid]) r = mid;
            else l = mid+1;
        }
        return l;
    }
    
    void updata(int &x, int l, int r, int k, int c){
        int fa = x;  
        if (!x) x = ++S;
        ls[x] = ls[fa], rs[x] = rs[fa], sum[x] = sum[fa]+c;
        if (l == r) return;
        int mid = (l+r) >> 1;
        if (k <= mid) updata(ls[x], l, mid, k, c);
        else updata(rs[x], mid+1, r, k, c);
    }
    
    int lowbit(int x) {
        return x & (-x);
    }
    
    void updata(int x, int k, int c){
        for (int i = x; i <= n; i += lowbit(i)) updata(root[i], 0, n, k, c);
    }
    
    int query(int a, int b, int k){
        int l = 0, r = n, mid, ret = 0, len1 = 0, len2 = 0, t = 0;
        for (int i = a; i; i -= lowbit(i)) t1[++len1] = root[i];
        for (int i = b; i; i -= lowbit(i)) t2[++len2] = root[i];
        while (l < r){
            mid = (l+r) >> 1;
    //        cout<<a<<" "<<b<<" t"<<b-a<<" l"<<l<<" r"<<r<<endl;
            if (k <= mid) {
                r = mid;
                for (int i = 1; i <= len1; i++) ret -= sum[rs[t1[i]]];
                for (int i = 1; i <= len2; i++) ret += sum[rs[t2[i]]];
                for (int i = 1; i <= len1; i++) t1[i] = ls[t1[i]];
                for (int i = 1; i <= len2; i++) t2[i] = ls[t2[i]];
            }
            else {
                l = mid+1;
                for (int i = 1; i <= len1; i++) t1[i] = rs[t1[i]];
                for (int i = 1; i <= len2; i++) t2[i] = rs[t2[i]];
            }
        }
        return ret;
    }
    
    void Solve(){
        int l, r, c;
        n++;
        for (int i = 1; i < n; i++) num[i] = find(num[i]), q[num[i]].insert(i);
        for (int i = 1; i < n; i++) updata(i, *q[num[i]].upper_bound(i), 1);//, updata(0, i, 1);
    //    cout<<query(1, 6, 6); 
        for (int i = 1; i <= m; i++){
            int l = op[i].l, r = op[i].r;
            if (op[i].s[0] == 'Q'){
                printf("%d
    ", query(l-1, r, r));
            }
            else {
                set<int>::iterator p;
                p = q[num[l]].lower_bound(l); p--;
                int t = *(p);
                if (t) {
                    updata(t, l, -1);
                    updata(t, *q[num[l]].upper_bound(l), 1);    
                }
                updata(l, *q[num[l]].upper_bound(l), -1);
                q[num[l]].erase(l);
                num[l] = find(op[i].r);
                q[num[l]].insert(l);
                p = q[num[l]].lower_bound(l); p--;
                t = *(p);
                if (t) {
                    updata(t, l, 1);
                    updata(t, *q[num[l]].upper_bound(l), -1);    
                }
                updata(l, *q[num[l]].upper_bound(l), 1);
            }
        }
    }
    
    int main(){
        Read_Data();
        Solve();
        return 0;
    }
  • 相关阅读:
    web高级第一节
    Socket网络编程
    redis第三节
    redis第二节
    Git(2)
    Xamarin.Android 应用程序配置
    Android--ListView与数据绑定(Xamarin)
    Android--Activity(活动)
    Xamarin Android 真机调试时闪退
    wpf 将Style应用到 ListView 中的 ListViewItem 元素
  • 原文地址:https://www.cnblogs.com/Lukaluka/p/5283865.html
Copyright © 2011-2022 走看看