• hdu 3854 Glorious Array(一般)


    Problem Description
    You are given a array with N nodes. The array nodes are numbered from 1 to N ( represented by a_i ). In the start, the color
    of any node in the array is white or black. We define that the "distance" between a and b is min{a_i| a<=i<=b} if a-th and bth
    nodes have diffrerent color, or infinite if they have the same color.
    We will ask you to perfrom some instructions of the following form:
    0 i : change the color of the i-th node (from white to black, or from black to white);
    or
    1 : ask for the kinds of diffrent pair of nodes' distance is less than K
     


    Input
    The first line contains a positive integer: the number of test cases, at most 100.
    After that per test case:
    One line with three integers N, m and K (1 ≤ N, m ≤ 1 00000, K ≤ 1000000): the length of the array, the number of
    instructions and K which used in operation 1 .
    Then comes a line with N intergers a_i (|a_i|<10000000).
    A line with N intergers c_i (c_i = 0(white) or 1(black)), which reprsent the color of N nodes.
    Next m lines, each will be a instruction described above.
     


    Output
    one interger for each operation 1.
     


    Sample Input
    1 5 3 2 2 3 1 4 2 0 1 0 1 1 1 0 2 1
     


    Sample Output
    5 6


    //

    题目描述:
    给你n个数,和每个数字的状态(0或者1)。
    有两种操作:
    第一种:翻转某个数字的状态。
    第二种:询问,要求输入满足条件的i, j组合个数。
    一个满足条件的i,j要求:
    A:1 <= i <= j <= n
    B: i和j数字的状态不同
    C:i和j的闭区间内的数字的最小值小于k(k由输入给定)
    解题报告:
    对于一开始的输入先求出组合个数。
    然后对于每次的翻转状态,更新组合个数:
    比如翻转i,如果x[i] < k, 那么只需看i左侧有多少个0或者1(具体看x[i]当前状态),和i右侧有多少个0或者1(同上),就可以知道这次翻转具体变化了多少,具体的实现可以用树状数组。
    如果x[i] > k,初始化时记下在i左侧最近的小于k的数字的位置L[i],同理R[i]。
    找到L[i]左侧0或者1的个数和R[i]右侧0或者1的个数,就是这次变化的个数。
    应该比较好理解。

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<string>
    #include<cstring>
    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<vector>
    #define tree int o,int l,int r
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define lo o<<1
    #define ro o<<1|1
    #define ULL unsigned long long
    #define LL long long
    #define inf 0x7fffffff
    #define eps 1e-7
    #define N 100009
    using namespace std;
    int T,n,m,k,t,maxv,x;
    int cl[N],c[N];
    int l[N],r[N];
    bool val[N];
    LL ans;
    void init()
    {
        ans=0;
        memset(c,0,sizeof(c));
        memset(cl,0,sizeof(cl));
    }
    void add(int x,int v)
    {
        while(x<N)
        {
            c[x]+=v;
            x+=x&-x;
        }
    }
    int sum(int x)
    {
        int ans=0;
        while(x>0)
        {
            ans+=c[x];
            x-=x&-x;
        }
        return ans;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("ex.in","r",stdin);
    #endif
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d",&n,&m,&k);
            init();
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&x);
                if(x<k)
                    val[i]=0;
                else
                    val[i]=1;
            }
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&cl[i]);
                if(cl[i])
                    add(i,cl[i]);
            }
            int x=0;
            for(int i=1; i<=n; i++)
            {
                if(val[i]==0)
                {
                    for(int j=i-1; j>x; j--)
                        l[j]=x,r[j]=i;
    
                    x=i;
    
                    l[i]=i;
                    r[i]=i;/////////////////
                }
            }
            for(int j=x+1; j<=n; j++)
                l[j]=x,r[j]=n+1;
    
            for(int i=1; i<=n; i++)
            {
                if(val[i]==0)//////////////
                {
                    ans+=i-1;
                    t=i-1;
                }
                else
                {
                    ans+=l[i];
                    t=l[i];
                }
    
                int num=sum(t),all=t;
                if(cl[i]==1)
                {
                    t=num;
                }
                else
                    t=(all-num);
                ans-=t;
    
            }
            while(m--)
            {
                scanf("%d",&x);
                if(x)
                {
                    printf("%I64d
    ",ans);
                }
                else
                {
                    scanf("%d",&x);
    
    //                        cout<<"x="<<x<<endl;
                    if(val[x]==0)
                    {
    //                    cout<<"========"<<endl;
                        int num=sum(n),t,all=n-1;
                        if(cl[x]==1)
                        {
                            num--;
    //                        cout<<"num="<<num<<endl;
                            t=num-(all-num);
                        }
                        else
                            t=(all-num)-num;
                        ans+=t;
                    }
                    else
                    {
                        int t,all=n-(r[x]-l[x]-1);
                        int num=sum(n)-sum(r[x]-1)+sum(l[x]);
                        if(cl[x]==1)
                        {
                            t=num-(all-num);
                        }
                        else
                            t=(all-num)-num;
                        ans+=t;
                    }
                    cl[x]=!cl[x];
                    if(!cl[x])
                        add(x,-1);
                    else
                        add(x,1);
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    IOS设计模式之四(备忘录模式,命令模式)
    IOS设计模式之三(适配器模式,观察者模式)
    IOS设计模式之二(门面模式,装饰器模式)
    IOS设计模式之一(MVC模式,单例模式)
    C#调用C++导出(dllexport)方法
    C# 多任务之 Task
    C# Remoting的一个简单例子
    C#中指针使用总结
    C# fixed详解
    C#中virtual和abstract的区别
  • 原文地址:https://www.cnblogs.com/sbaof/p/3286867.html
Copyright © 2020-2023  润新知