题意:给一些结点,每个结点是黑色或白色,并有一个权值。定义两个结点之间的距离为两个结点之间结点的最小权值当两个结点异色时,否则距离为无穷大。给出两种操作,一种是将某个结点改变颜色,另一个操作是询问当前距离小于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. samba的rpm包,只有tar.gz文件安装

    tar.gz包是源代码的包,不能直接运行,需要安装tar xvf samba-3.5.1.tar.gz cd samba-3.5.1 &&cd source3 &&./ ...

  2. resque 遍历加载job目录下的类

    <?php class resqueTest { public function actionWork() { #require dirname(__DIR__).'/commands/Test ...

  3. (转)MySQL命令行--导入导出数据库

    MySQL命令行导出数据库:   1,进入MySQL目录下的bin文件夹:cd MySQL中到bin文件夹的目录 如我输入的命令行:cd C:\Program Files\MySQL\MySQL Se ...

  4. Masonry+拖动

    最近遇到一个问题,用Masonry写的布局: 拖动其中某个view,拖动方法按传统的写成如下形式.如果view中的label更改text值,拖动之后的view就会回到最初被设定的位置. - (void ...

  5. POI 导出Excel

    package east.mvc.utils; import java.io.*; import java.lang.reflect.*; import java.text.SimpleDateFor ...

  6. Java 中的 static 使用之静态初始化块

    Java 中可以通过初始化块进行数据赋值.如: 在类的声明中,可以包含多个初始化块,当创建类的实例时,就会依次执行这些代码块.如果使用 static 修饰初始化块,就称为静态初始化块. 需要特别注意: ...

  7. 为ssh增加选项

    在使用ssh的时候,可以看到ssh有很多功能,什么-o , -e等等.如下图 需求,想要给ssh增加一个参数的功能.比如说我现在的需求就是执行ssh的时候可以增加一个选项,给我每次ssh的操作搭一个标 ...

  8. 连接mysql提示com.mchange.v2.resourcepool.BasicResourcePool

    1.com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@6ff9129c com.mchange.v2.resourc ...

  9. phonegap 3.3教程 地理信息api教程

    一 准备工作 phonegap3.3的地理信息教程.从零开始,首先要新建一个项目从命令行启动 可以看到这是默认的生成的www目录,在这个目录里是最原始的html文件,编译的时候在根据这里的文件生成an ...

  10. Beginning Windows Azure Development Guide

    目  录 一 初始化Windows Azure 二 云应用程序的编写. 2.1云应用程序的创建. 2.2一个简单的云应用程序. 2.3 托管云程序. 三 云程序的数据库操作. 3.1通过Cloud平台 ...