zoukankan      html  css  js  c++  java
  • hdu 3275(线段树的延迟标记,我被坑了)

    题意:给你一个n(代表n个0或者1)和k(一次可以更新k个数),问把它们全部变成1至少需要多少步,如果无法实现则输出-1。

    思路:此题用到了贪心的思想,通过举例可以发现:从左边开始一碰到0就更新一次是最优解;然后接下来的是线段树的延迟标记,但是坑爹的是:我的数组开了100005*4一直是Runtime Error,后来改了100005*6之后才AC了,中间花费了我好多时间去查错,气死我了!!!

    代码实现:

    #include<iostream>
    #include<cstring>
    using namespace std;
    struct node{
        int num;
        int flag;
        int l;
        int r;
        int len;
    }p[100005*6];//坑爹的数组
    int n,k,nima,cao;
    char a[100005];
    void build(int l,int r,int n)//建树
    {
        p[n].l=l;
        p[n].r=r;
        p[n].len=r-l+1;
        p[n].flag=0;
        if(l==r)
        {
            if(a[l]=='1')
                p[n].num=0;
            else 
                p[n].num=1;
        }
        else
        {
            int mid=(l+r)/2;
            build(l,mid,n*2);
            build(mid+1,r,n*2+1);
            p[n].num=p[n*2].num+p[n*2+1].num;
        }
    }
    void pushdown(int n)//往下更新
    {
        p[n].flag=0;
        p[n*2].flag^=1;
        p[n*2+1].flag^=1;
        p[n*2].num=p[n*2].len-p[n*2].num;
        p[n*2+1].num=p[n*2+1].len-p[n*2+1].num;
    }
    void update(int x,int y,int n)//更新操作
    {     
        if(x==p[n].l&&y==p[n].r)
        {
            p[n].flag^=1;
            p[n].num=p[n].len-p[n].num;
        }
        else
        {
            int mid=(p[n].l+p[n].r)/2;
            if(x>mid)
                update(x,y,n*2+1);
            else if(y<=mid)
                update(x,y,n*2);
            else
            {
                update(x,mid,n*2);
                update(mid+1,y,n*2+1);
            }
        }
    }
    void insert(int x,int n)//查找0的位置,nima返回的也是0的位置,如果nima=0,则说明全是1了
    {
        if(nima)
            return ;
        if(p[n].flag==1)
            pushdown(n);
        if(p[n].l==p[n].r)
        {
            if(p[n].num==1)
            {
                nima=p[n].l;
                if(p[n].l+k-1<=cao)
                    update(p[n].l,p[n].l+k-1,1);
            }
        }
        else 
        {
            int mid=(p[n].l+p[n].r)/2;
            if(x>mid)
                insert(x,n*2+1);
            else 
            {
                insert(x,n*2);
                insert(mid+1,n*2+1);
            }
        }
    }
    int main()
    {
       int temp,t;
       while(scanf("%d%d",&n,&k)!=EOF&&(n!=0||k!=0))
       {
           cao=n;
           temp=0;
           t=0;
           getchar();
           scanf("%s",a+1);
           build(1,n,1);
           if(p[1].num==0)
           {
               printf("0\n");
               continue;
           }
           if(k==0)//特殊情况
           {
               printf("-1\n");
               continue;
           }
           while(1)
           {
              nima=0;
              insert(temp+1,1);
              temp=nima;
              if(nima==0)
                  break;
              if(n-temp+1<k)
                  break;
              t++;
           }
           if(nima==0)
               printf("%d\n",t);
           else
               printf("-1\n");
       }
       return 0;
    }
  • 相关阅读:
    python note 30 断点续传
    python note 29 线程创建
    python note 28 socketserver
    python note 27 粘包
    python note 26 socket
    python note 25 约束
    Sed 用法
    python note 24 反射
    python note 23 组合
    python note 22 面向对象成员
  • 原文地址:https://www.cnblogs.com/jiangjing/p/2943024.html
Copyright © 2011-2022 走看看