题意:给一些结点,每个结点是黑色或白色,并有一个权值。定义两个结点之间的距离为两个结点之间结点的最小权值当两个结点异色时,否则距离为无穷大。给出两种操作,一种是将某个结点改变颜色,另一个操作是询问当前距离小于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. Dynamics AX 2012 R2 配置报表服务器

    今天Reinhard在使用报表的过程中,发现以下错误: The default Report Server Configuration ID could not be found in the SRS ...

  2. [转]Win7 64位搭建本地SVN服务器 Apache+Subversion

    转载地址:http://blog.sina.com.cn/s/blog_4f072a7001015j5z.html 一.工具下载 01.SVN 服务器Subversion:Setup-Subversi ...

  3. HDU 4944 FSF’s game 一道好题

    FSF’s game Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tota ...

  4. WPFの静态资源(StaticResource)和动态资源(DynamicResource)

    下面是前台代码: <Window.Resources>        <TextBlock x:Key="res1" Text="好好学习"/ ...

  5. R开发环境(Eclipse+StatET)

    引用:http://cos.name/2008/12/eclipse-statet-for-r-editor/ StatET(www.walware.de/goto/statet) 1. 安装软件 s ...

  6. LabVIEW有限状态机

    顺序模式是我们最先接触,也是最基本的一种编程模式, 程序按照固定的顺序依次执行,结束(如图1) 但在很多情况下,静态的顺序模式并不能满足我们编程的要求,我们需要更有效地动态结构来实时改变程序的执行顺序 ...

  7. 深入浅出设计模式——观察者模式(Observer Pattern)

    模式动机 建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应.在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而 ...

  8. js string to int

    一.js中string转int有两种方式 Number() 和 parseInt() <script>     var   str='1250' ;  alert( Number(str) ...

  9. Android各组件/控件间通信利器之EventBus

    实际项目开发过程中,经常遇到如下场景:不同的应用程序组件的控件间具有一定的相互关联性,其中用户对后者进行的某种操作会引起前者的相应改变.举一个具体的场景:以糗事百科为例,在糗事列表页和详情页页,对于每 ...

  10. [分享] 从定制Win7母盘到封装详细教程 By BILL ( 10月23日补充说明 )

    [分享] 从定制Win7母盘到封装详细教程 By BILL ( 10月23日补充说明 ) billcheung 发表于 2011-10-23 00:07:49 https://www.itsk.com ...