题意:给一些结点,每个结点是黑色或白色,并有一个权值。定义两个结点之间的距离为两个结点之间结点的最小权值当两个结点异色时,否则距离为无穷大。给出两种操作,一种是将某个结点改变颜色,另一个操作是询问当前距离小于K的结点有多少对,K是一个定值。

思路:先求最初时候小于k的结点有多少对,然后每次改变颜色的时候,统计该点左侧和右侧各有多少同色和异色的结点(这一步使用树状数组),分别处理就行。另外需要预处理离某个结点最近的两个距离小于K的结点的位置。

代码写的略乱。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<time.h>
#include<iostream>
#define INF 10000000
#define LL long long
using namespace std;
int n,K;
vector<int> vec;
];
struct BIT
{
    ];
    void clear()
    {
        memset(dat,,sizeof(dat));
    }
    int lowBit(int x)
    {
        return -x&x;
    }
    int getSum(int x)
    {
        ;
        )
        {
            s+=dat[x];
            x-=lowBit(x);
        }
        return s;
    }
    void addVal(int x,int c)
    {
        ) return;
        while(x<=n)
        {
            dat[x]+=c;
            x+=lowBit(x);
        }
    }
    void setVal(int x,int c)
    {
        );
        addVal(x,-old+c);
    }
    int getCol(int x)
    {
        );
    }
    int countBlack(int ql,int qr)
    {
        ;
        );
    }
    int countWhite(int ql,int qr)
    {
        ;
        int s=countBlack(ql,qr);
        -s;
    }
};
BIT tree;
],rightM[];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int m;
        scanf("%d%d%d",&n,&m,&K);
        vec.clear();
        ; i<=n; ++i)
        {
            int val;
            scanf("%d",&val);
            if(val<K)
                vec.push_back(i);
        }
        tree.clear();
        ; i<=n; ++i)
        {
            int val;
            scanf("%d",&val);
            tree.setVal(i,val);
            ;
            int r=lower_bound(vec.begin(),vec.end(),i)-vec.begin();
            ) leftM[i]=-;
            else leftM[i]=vec[l];
            ;
            else rightM[i]=vec[r];
        }
        LL sum=;
        ,end;
        ; i<vec.size(); ++i)
        {
            last=(i==)?:vec[i-]+;
            end=(i==vec.size()-)?n:vec[i+];
            LL lb=tree.countBlack(last,vec[i]-),rw=tree.countWhite(vec[i]+,n);
            LL lw=tree.countWhite(last,vec[i]-),rb=tree.countBlack(vec[i]+,n);
            sum+=lb*rw;
            sum+=lw*rb;
            int col=tree.getCol(vec[i]);
            )
                sum+=lb+rb;
            else
                sum+=lw+rw;
        }
        while(m--)
        {
            int p;
            scanf("%d",&p);
            ) printf("%I64d\n",sum);
            else
            {
                int x;
                scanf("%d",&x);
                int old=tree.getCol(x);
                )
                {
                    )
                    {
                        LL lw,lb;
                        if(leftM[x]==x)
                        {
                            lw=tree.countWhite(,leftM[x]-);
                            lb=tree.countBlack(,leftM[x]-);
                        }
                        else
                        {
                            lw=tree.countWhite(,leftM[x]);
                            lb=tree.countBlack(,leftM[x]);
                        }
                        sum-=lw;
                        sum+=lb;
                    }
                    )
                    {
                        LL rw,rb;
                        if(rightM[x]==x)
                        {
                            rb=tree.countBlack(rightM[x]+,n);
                            rw=tree.countWhite(rightM[x]+,n);
                        }
                        else
                        {
                            rb=tree.countBlack(rightM[x],n);
                            rw=tree.countWhite(rightM[x],n);
                        }
                        sum-=rw;
                        sum+=rb;
                    }
                }
                else
                {
                    )
                    {
                        LL lw,lb;
                        if(leftM[x]==x)
                        {
                            lw=tree.countWhite(,leftM[x]-);
                            lb=tree.countBlack(,leftM[x]-);
                        }
                        else
                        {
                            lw=tree.countWhite(,leftM[x]);
                            lb=tree.countBlack(,leftM[x]);
                        }
                        sum+=lw;
                        sum-=lb;
                    }
                    )
                    {
                        LL rw,rb;
                        if(rightM[x]==x)
                        {
                            rb=tree.countBlack(rightM[x]+,n);
                            rw=tree.countWhite(rightM[x]+,n);
                        }
                        else
                        {
                            rb=tree.countBlack(rightM[x],n);
                            rw=tree.countWhite(rightM[x],n);
                        }
                        sum+=rw;
                        sum-=rb;
                    }
                }
                tree.setVal(x,old^);
            }
        }
    }
    ;
}

HDU 3854 Glorious Array(树状数组)的更多相关文章

  1. hdu 5775 Bubble Sort 树状数组

    Bubble Sort 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5775 Description P is a permutation of t ...

  2. HDU 3333 | Codeforces 703D 树状数组、离散化

    HDU 3333:http://acm.hdu.edu.cn/showproblem.php?pid=3333 这两个题是类似的,都是离线处理查询,对每次查询的区间的右端点进行排序.这里我们需要离散化 ...

  3. HDU 3333 - Turing Tree (树状数组+离线处理+哈希+贪心)

    题意:给一个数组,每次查询输出区间内不重复数字的和. 这是3xian教主的题. 用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理.在线很难下手,考虑离线处理. 将所有查询区间从右端点由 ...

  4. HDU 3333 Turing Tree (树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3333 题意就是询问区间不同数字的和. 比较经典的树状数组应用. //#pragma comment(l ...

  5. HDU 4638 Group 【树状数组,分块乱搞(莫队算法?)】

    根据题目意思,很容易得出,一个区间里面连续的段数即为最少的group数. 题解上面给的是用树状数组维护的. 询问一个区间的时候,可以一个一个的向里面添加,只需要判断a[i]-1 和 a[i]+1是否已 ...

  6. HDU 4325 Flowers(树状数组+离散化)

    http://acm.hdu.edu.cn/showproblem.php?pid=4325 题意:给出n个区间和m个询问,每个询问为一个x,问有多少个区间包含了x. 思路: 因为数据量比较多,所以需 ...

  7. HDU - 1541 Stars 【树状数组】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1541 题意 求每个等级的星星有多少个 当前这个星星的左下角 有多少个 星星 它的等级就是多少 和它同一 ...

  8. HDU 3874 Necklace (树状数组 | 线段树 的离线处理)

    Necklace Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  9. HDU 5101 Select --离散化+树状数组

    题意:n 组,每组有一些值,求 在不同的两组中每组选一个使值的和大于k的方法数. 解法:n * Cnt[n] <= 1000*100 = 100000, 即最多10^5个人,所以枚举每个值x,求 ...

随机推荐

  1. iOS中Block的基础用法

    本文简介 本章不会对Block做过多的实现研究.只是讲解基本的用法.纯粹基础知识.结合实际项目怎么去做举例.Block使用场景,可以在两个界面的传值,也可以对代码封装作为参数的传递等.用过GCD就知道 ...

  2. MYSQL转换JSON

    http://51strive.com/ <!DOCTYPE html><html><head><meta charset="UTF-8" ...

  3. C语言运算符和优先级

    关于C语言运算符和优先级,经整理众多博客资料汇入自己的实战,如下:        a.算术运算        C语言一共有34种运算符,包括常见的加减乘除运算.        1) 加法:+ 还可以表 ...

  4. 理解JS回调函数

    我们经常会用到客户端与Web项目结合开发的需求,那么这样就会涉及到在客户端执行前台动态脚本函数,也就是函数回调,本文举例来说明回调函数的过程. 首先创建了一个Web项目,很简单的一个页面,只有一个bu ...

  5. SQL SERVER建库&用户赋权限

    create database ServiceDB on primary ( name='ServiceDB_data', -- 主数据文件的逻辑名称 filename='D:\WebRoot\DB\ ...

  6. 《BI项目笔记》创建时间维度(2)

    创建步骤:   序号 选择的属性 重命名后的名称 属性类别 1 DateKey DateKey 常规 2 Month Key Month Key 月份 3 English Month Name Eng ...

  7. Google Protocol Buffer的安装与.proto文件的定义

    什么是protocol Buffer呢? Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准. 我理解的就是:它是一种轻便高效的结构 ...

  8. Spring + Mybatis 使用 PageHelper 插件分页

    原文:http://www.cnblogs.com/yucongblog/p/5330886.html 先增加maven依赖: <dependency> <groupId>co ...

  9. phalcon: update修改数据却变成了insert插入数据

    phalcon: 在对表进行操作是,update修改数据却变成了insert插入数据. 发现,update的时,无论怎么加where都会变成了insert插入数据. 检查了一下表,原来是表没有 主键引 ...

  10. 解决maven的报错

    昨晚用Mars版本建maven工程,测试springboot,一路很顺畅,没有啥阻碍. 今天换了台机器,结果就不好用了,建完maven工程后,pom文件报错,该生成的代码结构也没有,更别提jar包了. ...