zoukankan      html  css  js  c++  java
  • C

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6534

    这个题,首先可以离线,又是区间。那么离线区间我们很容易想到莫队进行操作。

    所以现在的问题转换为,如何求一个数的贡献。因为莫队的操作是一个数一个数的增加。

    我们需要求得是增加这个数,会增加多少个对数,删除这个数,会删除多少对数。

    假设:增加一个数x。那么他能影响的是[x-k,x+k]这个区间,所以我们在增加的时候,需要计算值域[x-k,x+k]这个区间有多少个数。

    删除一个数同理。

    注意到,是求值域区间内有多少个数。那很自然的想到树状数组。

    故代码如下:

    #include"stdio.h"
    #include"string.h"
    #include"math.h"
    #include"algorithm"
    using namespace std;
    #define isdigit(x) ((x) >= '0' && (x) <= '9')
    inline int read() {
        int res = 0;
        char c = getchar();
        while(!isdigit(c)) c = getchar();
        while(isdigit(c)) res = (res << 1) + (res << 3) + (c ^ 48), c = getchar();
        return res;
    }
    
    const int N = 500010;
    struct Node{
        int l,r,id;
    }node[N];
    
    int n,m,k;
    int val[N],cnt[N],result[N];
    int belong[N],Size,bnum;
    int a[N]; int C[N],len;
    int id[N];int now;
    
    inline int lowbit(int x){return x & (-x);}
    
    inline int getsum(int x){
        int res = 0;
        for(int i = x; i > 0; i -= lowbit(i)){///在这里吃了大亏,调了好久,把lowbit(i)写成了lowbit(x),哭呀
            res += C[i];
        }
        return res;
    }
    inline void update(int x,int v){
        for(int i = x; i <= len; i += lowbit(i)){
            C[i] += v;
        }
    }
    
    inline int cmp(Node a,Node b)
    {
        return (belong[a.l] ^ belong[b.l]) ? belong[a.l] < belong[b.l] : ((belong[a.l] & 1) ? a.r < b.r : b.r < a.r);
    }
    
    inline void del(int L)
    {
        int x = a[val[L]];
        int lx = x - k;int rx = x + k;
        int l = lower_bound(a + 1,a + len + 1,lx) - a;
        int r = lower_bound(a + 1,a + len + 1,rx) - a;
        if(r > len || a[r] > rx) r --;///在这里又吃了大亏,只考虑了r>len的情况。没有考虑a[r]>rx的情况。因为一开始傻傻的认为rx一定会在a数组中出现。我是智障一啊
        int q1 = getsum(r); int q2 = getsum(l - 1);
        now = now - (q1 - q2) + 1;
        update(val[L],-1);
    }
    
    inline void add(int L){
        int x = a[val[L]];
        int lx = x - k;int rx = x + k;
        int l = lower_bound(a + 1,a + len + 1,lx) - a;
        int r = lower_bound(a + 1,a + len + 1,rx) - a;
        if(r > len || a[r] > rx) r --;
        int q1 = getsum(r); int q2 = getsum(l - 1);
        now += q1 - q2;
        update(val[L],1);
    }
    int main()
    {
        n = read(); m = read(); k = read();
        for(int i = 1; i <= n; i ++) val[i] = a[i] = read();
        sort(a + 1,a + n + 1);
        len = unique(a + 1,a + n + 1) - a - 1;
        for(int i = 1; i <= n; i ++){
            val[i] = lower_bound(a + 1,a + len + 1,val[i]) - a;
        }
    
        Size = sqrt(n); bnum = ceil((double)n / Size);
        for(int i = 1; i <= bnum; i ++)
            for(int j = (i - 1) * Size + 1; j <= i * Size; j ++)
               belong[j] = i;
        for(int i = 1; i <= m; i ++)
        {
            node[i].l = read(); node[i].r = read();
            node[i].id = i;
        }
        sort(node + 1,node + m + 1,cmp);
    
        int L = 1,R = 0;now = 0;
        for(int i = 1; i <= m; i ++)
        {
            int ql = node[i].l,qr = node[i].r;
              while(R < qr){
                ++ R;
                add(R);
            }
            while(R > qr){
               del(R); R --;
            }
            while(L < ql){
               del(L);  L ++;
            }
            while(L > ql){
                -- L;
               add(L);
            }
            result[node[i].id] = now;
        }
        for(int i = 1; i <= m; i ++)
            printf("%d
    ",result[i]);
    }
    
  • 相关阅读:
    codeforces 439C 模拟
    codeforces 435B
    【WebVR】AFrame中的A-sky无法利用src指定路径显示全景图
    【UE4】添加头文件之后VS中UCLASS()报错问题解决办法
    【UE4】蓝图之间的通讯
    git中报unable to auto-detect email address 错误的解决办法
    2017ACM省赛总结与生涯回顾
    hihocoder#1121 : 二分图一•二分图判定
    hihocoder#1039 : 字符消除
    2048low版
  • 原文地址:https://www.cnblogs.com/yrz001030/p/12367917.html
Copyright © 2011-2022 走看看