码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3854 Glorious Array(树状数组)

时间:2014-08-13 22:18:17      阅读:283      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   使用   os   io   for   

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

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

代码写的略乱。

bubuko.com,布布扣
#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;
int col[100005];
struct BIT
{
    int dat[100005];
    void clear()
    {
        memset(dat,0,sizeof(dat));
    }
    int lowBit(int x)
    {
        return -x&x;
    }
    int getSum(int x)
    {
        int s=0;
        while(x>0)
        {
            s+=dat[x];
            x-=lowBit(x);
        }
        return s;
    }
    void addVal(int x,int c)
    {
        if(x<=0) return;
        while(x<=n)
        {
            dat[x]+=c;
            x+=lowBit(x);
        }
    }
    void setVal(int x,int c)
    {
        int old=getSum(x)-getSum(x-1);
        addVal(x,-old+c);
    }
    int getCol(int x)
    {
        return getSum(x)-getSum(x-1);
    }
    int countBlack(int ql,int qr)
    {
        if(qr<ql) return 0;
        return getSum(qr)-getSum(ql-1);
    }
    int countWhite(int ql,int qr)
    {
        if(qr<ql) return 0;
        int s=countBlack(ql,qr);
        return qr-ql+1-s;
    }
};
BIT tree;
int leftM[100005],rightM[100005];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int m;
        scanf("%d%d%d",&n,&m,&K);
        vec.clear();
        for(int i=1; i<=n; ++i)
        {
            int val;
            scanf("%d",&val);
            if(val<K)
                vec.push_back(i);
        }
        tree.clear();
        for(int i=1; i<=n; ++i)
        {
            int val;
            scanf("%d",&val);
            tree.setVal(i,val);
            int l=upper_bound(vec.begin(),vec.end(),i)-vec.begin()-1;
            int r=lower_bound(vec.begin(),vec.end(),i)-vec.begin();
            if(l<0) leftM[i]=-1;
            else leftM[i]=vec[l];
            if(r>=vec.size()) rightM[i]=-1;
            else rightM[i]=vec[r];
        }
        LL sum=0;
        int last=1,end;
        for(int i=0; i<vec.size(); ++i)
        {
            last=(i==0)?1:vec[i-1]+1;
            end=(i==vec.size()-1)?n:vec[i+1];
            LL lb=tree.countBlack(last,vec[i]-1),rw=tree.countWhite(vec[i]+1,n);
            LL lw=tree.countWhite(last,vec[i]-1),rb=tree.countBlack(vec[i]+1,n);
            sum+=lb*rw;
            sum+=lw*rb;
            int col=tree.getCol(vec[i]);
            if(col==0)
                sum+=lb+rb;
            else
                sum+=lw+rw;
        }
        while(m--)
        {
            int p;
            scanf("%d",&p);
            if(p==1) printf("%I64d\n",sum);
            else
            {
                int x;
                scanf("%d",&x);
                int old=tree.getCol(x);
                if(old==1)
                {
                    if(leftM[x]!=-1)
                    {
                        LL lw,lb;
                        if(leftM[x]==x)
                        {
                            lw=tree.countWhite(1,leftM[x]-1);
                            lb=tree.countBlack(1,leftM[x]-1);
                        }
                        else
                        {
                            lw=tree.countWhite(1,leftM[x]);
                            lb=tree.countBlack(1,leftM[x]);
                        }
                        sum-=lw;
                        sum+=lb;
                    }
                    if(rightM[x]!=-1)
                    {
                        LL rw,rb;
                        if(rightM[x]==x)
                        {
                            rb=tree.countBlack(rightM[x]+1,n);
                            rw=tree.countWhite(rightM[x]+1,n);
                        }
                        else
                        {
                            rb=tree.countBlack(rightM[x],n);
                            rw=tree.countWhite(rightM[x],n);
                        }
                        sum-=rw;
                        sum+=rb;
                    }
                }
                else
                {
                    if(leftM[x]!=-1)
                    {
                        LL lw,lb;
                        if(leftM[x]==x)
                        {
                            lw=tree.countWhite(1,leftM[x]-1);
                            lb=tree.countBlack(1,leftM[x]-1);
                        }
                        else
                        {
                            lw=tree.countWhite(1,leftM[x]);
                            lb=tree.countBlack(1,leftM[x]);
                        }
                        sum+=lw;
                        sum-=lb;
                    }
                    if(rightM[x]!=-1)
                    {
                        LL rw,rb;
                        if(rightM[x]==x)
                        {
                            rb=tree.countBlack(rightM[x]+1,n);
                            rw=tree.countWhite(rightM[x]+1,n);
                        }
                        else
                        {
                            rb=tree.countBlack(rightM[x],n);
                            rw=tree.countWhite(rightM[x],n);
                        }
                        sum+=rw;
                        sum-=rb;
                    }
                }
                tree.setVal(x,old^1);
            }
        }
    }
    return 0;
}
View Code

 

HDU 3854 Glorious Array(树状数组),布布扣,bubuko.com

HDU 3854 Glorious Array(树状数组)

标签:style   blog   http   color   使用   os   io   for   

原文地址:http://www.cnblogs.com/kkkwjx/p/3911182.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!