zoukankan      html  css  js  c++  java
  • BZOJ1106: [POI2007]立方体大作战tet

    【传送门:BZOJ1106


    简要题意:

      有n种数,每种数有两个,给出一个2*n的序列,表示每个数在栈中的位置,可以任意交换相邻两个位置的数,若相邻两个数为同种数,则这两个数从栈中移除,然后所有上面的数都会掉落并形成连锁反应,求出移除所有数的最少步数


    题解:

      树状数组水题

      若当前第i个位置出现的这个数是第一次出现,则将i位置+1,否则求出第一次出现的位置+1到第i个位置的数的个数(相当于将这个数消除所需的步数)

      如何证明正确性:实际上是贪心,因为只有当出现1212这样的情况才会需要步数,不然就会在掉落的时候消除


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<cstdlib>
    using namespace std;
    int a[110000],n;
    int lowbit(int x){return x&-x;}
    void change(int x,int d)
    {
        while(x<=2*n)
        {
            a[x]+=d;
            x+=lowbit(x);
        }
    }
    int getsum(int x)
    {
        int ans=0;
        while(x!=0)
        {
            ans+=a[x];
            x-=lowbit(x);
        }
        return ans;
    }
    int pos[51000];
    int main()
    {
        scanf("%d",&n);
        memset(pos,0,sizeof(pos));
        memset(a,0,sizeof(a));
        int ans=0;
        for(int i=1;i<=2*n;i++)
        {
            int x;
            scanf("%d",&x);
            if(pos[x]==0)
            {
                pos[x]=i;
                change(pos[x],1);
            }
            else
            {
                ans+=getsum(i)-getsum(pos[x]);
                change(pos[x],-1);
            }
        }
        printf("%d
    ",ans);
        return 0;
    }

     

  • 相关阅读:
    CSS中的小知识
    网络基础 中的osi七层 协议
    pickle的使用
    max()的key的运用
    read,readline,readlines的区别
    print()控制台输出带颜色的方法
    写项目时bin目录下的start中的细节(路径问题的解决)
    使用hashlib密文存储实例
    固态硬盘使用f2fs作为根分区安装linux
    工厂方法(Factory Method)
  • 原文地址:https://www.cnblogs.com/Never-mind/p/9729732.html
Copyright © 2011-2022 走看看