题意:给一些结点,每个结点是黑色或白色,并有一个权值。定义两个结点之间的距离为两个结点之间结点的最小权值当两个结点异色时,否则距离为无穷大。给出两种操作,一种是将某个结点改变颜色,另一个操作是询问当前距离小于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. 覆盖的面积(HDU 1255 线段树)

    覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem D ...

  2. HTML 事件属性(下)

    HTML 事件属性(下) 一:键盘事件 (Keyboard Events)二:鼠标事件 (Mouse Events) 一:键盘事件 (Keyboard Events)在下列元素中无效:base.bdo ...

  3. hdu 3966 Aragorn's Story 树链剖分 按点

    Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. 如何在iPhone与iPad上开启firebug

    原文: MARTIN KOOL games - web - dad - sarien.net - q42 - livejs - handcraft How to use Firebug on your ...

  5. Javasocket1

    转载自http://www.cnblogs.com/linzheng/archive/2011/01/23/1942328.html java socket编程 一,网络编程中两个主要的问题 一个是如 ...

  6. hihoCoder 1383 : The Book List(书目表)

    hihoCoder #1383 : The Book List(书目表) 时间限制:1000ms 单点时限:1000ms 内存限制:256MB Description - 题目描述 The histo ...

  7. 《BI那点儿事》数据流转换——百分比抽样、行抽样

    百分比抽样和行抽样可以从数据源中随机选择一组数据.这两种task都可以产生两组输出,一组是随机选择的,另一组是没有被选择的.可以将这些选择出的数据发送到开发或者测试服务器上.这个Task的最合适的应用 ...

  8. 从欧几里得距离、向量、皮尔逊系数到http://guessthecorrelation.com/

    一.欧几里得距离就是向量的距离公式 二.皮尔逊相关系数反应的就是线性相关 游戏http://guessthecorrelation.com/ 的秘诀也就是判断一组点的拟合线的斜率y/x ------- ...

  9. java高薪之路__002_异常处理

    自定义异常 package learn.JavaBasics.Class; import java.util.Date; /** * 如何自定义一个异常类 * 1. 继承一个现有的异常类 * 2. 提 ...

  10. windows+linux开发环境 解决laravel blade模板缓存问题

    编码环境windows10 编码IDE:phpstorm 2016.2 PHP框架:laravel5.3 + 代码运行环境:centos7 + nginx 在开发过程中,上传blade模板文件到lin ...