• CF 85D Sum of Medians


    CF_85D

        这个题目可以用sum[cur][i]表示第cur个节点所辖区间的下标模5为i的整数之和,这样只要再加一个表示节点所辖区间的整数数目的标记num[cur],每次就可以方便的计算出sum[cur][i]的值了

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #define MAXD 100010
    struct Question
    {
        char b[5];
        int x;
    }question[MAXD];
    int N, num[4 * MAXD], tx[MAXD], X;
    long long int sum[4 * MAXD][5];
    int cmp(const void *_p, const void *_q)
    {
        int *p = (int *)_p, *q = (int *)_q;
        return *p < *q ? -1 : 1;
    }
    void build(int cur, int x, int y)
    {
        int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
        memset(sum[cur], 0, sizeof(sum[cur]));
        num[cur] = 0;
        if(x == y)
            return ;
        build(ls, x, mid);
        build(rs, mid + 1, y);
    }
    void init()
    {
        int i, j, k;
        for(i = k = 0; i < N; i ++)
        {
            scanf("%s", question[i].b);
            if(question[i].b[0] == 'a' || question[i].b[0] == 'd')
            {
                scanf("%d", &question[i].x);
                tx[k ++] = question[i].x;
            }
        }
        qsort(tx, k, sizeof(tx[0]), cmp);
        X = 0;
        for(i = 0; i < k; i ++)
            if(i == 0 || tx[i] != tx[i - 1])
                tx[X ++] = tx[i];
        if(X)
            build(1, 0, X - 1);
    }
    int BS(int x)
    {
        int mid, min = 0, max = X;
        for(;;)
        {
            mid = (min + max) >> 1;
            if(mid == min)
                break;
            if(tx[mid] <= x)
                min = mid;
            else
                max = mid;
        }
        return mid;
    }
    void update(int cur)
    {
        int i, ls = cur << 1, rs = (cur << 1) | 1;
        num[cur] = num[ls] + num[rs];
        for(i = 0; i < 5; i ++)
            sum[cur][i] = sum[ls][i] + sum[rs][(i + 5 - num[ls] % 5) % 5];
    }
    void refresh(int cur, int x, int y, int k, int c)
    {
        int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
        if(x == y)
        {
            if(c)
                num[cur] = 1, sum[cur][0] = tx[k];
            else
                num[cur] = 0, sum[cur][0] = 0;
            return ;
        }
        if(k <= mid)
            refresh(ls, x, mid, k, c);
        else
            refresh(rs, mid + 1, y, k, c);
        update(cur);
    }
    void ADD(int x)
    {
        int k = BS(x);
        refresh(1, 0, X - 1, k, 1);
    }
    void Del(int x)
    {
        int k = BS(x);
        refresh(1, 0, X - 1, k, 0);
    }
    void solve()
    {
        int i, j, k;
        for(i = 0; i < N; i ++)
        {
            if(question[i].b[0] == 'a')
                ADD(question[i].x);
            else if(question[i].b[0] == 'd')
                Del(question[i].x);
            else
                printf("%I64d\n", sum[1][2]);
        }
    }
    int main()
    {
        while(scanf("%d", &N) == 1)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    乘坐飞机时,有什么事情是机长和机上工作人员不想让乘客知道的?
    北京有哪些被废弃的地方值得一看?推荐理由是什么?
    在读硕士或博士是如何养活自己的?
    怎样有效提高记忆力?
    北京值得去的、不为人知的景点(或展览馆、美术馆、公园)有哪些?
    你收藏了哪些藏品?
    如何抓到入侵网站的黑客?
    中国姓氏的区域性?
    python之入门,你好,中国
    Eclipse 内置浏览器
  • 原文地址:https://www.cnblogs.com/staginner/p/2452847.html
Copyright © 2020-2023  润新知