• 2015 多校联赛 ——HDU5372(树状数组)


    Sample Input
    3 0 0 0 3 0 1 5 0 1 0 0 1 1 0 1 0 0
     
    Sample Output
    Case #1: 0 0 0 Case #2: 0 1 0 2

    有0,1两个操作,0  x代表添加从x 到 x + i(带表第i次添加)的线段,每次添加时问被其覆盖的线段有多少。

                               1  x代表删除第i次添加的。

    思路:每一次添加后,求出小于x的左节点个数x1,小于等于y的右节点个数x2。 x2- x1即可

    改变单个节点,所以树状数组更加合适


    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    #define N 200050
    #define mod 258280327
    
    int le[N],re[N],lr[N],rr[N];
    int oper[N],Left[N],Right[N],id[N];
    int c[N];
    int tot;
    
    int lowbit(int x)
    {
        return x&-x;
    }
    void update(int *c,int n,int k,int v)
    {
        while(k <= n)
        {
            c[k] += v;
            k += lowbit(k);
        }
    }
    
    int query(int *c ,int k)
    {
        int ans = 0;
        while(k > 0)
        {
            ans += c[k];
            k -= lowbit(k);
        }
        return ans;
    }
    
    
    int main()
    {
        //freopen("4.txt","r",stdin);
        int cas=1,L=1,l,ans,nul,nur,n,Q;
        while(scanf("%d",&n)!=EOF)
        {
            Q = nul = nur = 0;
            for(int i = 1; i <= n; i++)
            {
                scanf("%d%d",&oper[i],&l);
                if(oper[i] == 0)
                {
                    id[++Q] = i;
                    le[i] = l;
                    re[i] = l+L;
                    Left[nul++] = le[i];
                    Right[nur++] = re[i];
                    L++;
                }
                else
                {
                    le[i] = l;
                }
            }
            printf("Case #%d:
    ",cas++);
    
            memset(lr,0,sizeof(lr));
            memset(rr,0,sizeof(rr));
    
            sort(Left, Left + nul);
            nul = unique(Left, Left + nul) - Left;
            sort(Right, Right + nur);
            nur = unique(Right, Right + nur) - Right;
    
            for(int i = 1; i <= n; i++)
            {
                if(oper[i] == 0)
                {
                    int x1 = lower_bound(Left,Left+nul,le[i]) - Left + 1;
                    int x2 = lower_bound(Right,Right+nur,re[i]) - Right + 1;
                    ans = query(rr,x2)-query(lr,x1-1);
                    update(rr,nur,x2,1);
                    update(lr,nul,x1,1);
                    printf("%d
    ",ans);
                }
                else
                {
                    int v = id[le[i]];
                    int x1 = lower_bound(Left,Left+nul,le[v]) - Left + 1;
                    int x2 = lower_bound(Right,Right+nur,re[v]) - Right + 1;
                    update(lr,nul,x1,-1);
                    update(rr,nur,x2,-1);
                }
            }
        }
        return 0;
    }
    

      









  • 相关阅读:
    flutter canvas 简单绘画直线
    Yapi 部署及遇到的坑
    flutter 时间选择器第三方插件返回时间格式说明
    windows + flutter + vscode 连接其他模拟器
    flutter 配置环境
    flutter 返回键监听
    flutter 自定义主题切换
    flutter Provide 状态管理篇
    flutter 本地存储 (shared_preferences)
    JS做倒计时的例题
  • 原文地址:https://www.cnblogs.com/Przz/p/5409779.html
Copyright © 2020-2023  润新知