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;
    }
  • 相关阅读:
    自己动手写动态网站
    CompareValidator控件
    跨数据库服务器查询和跨表更新
    在Windows 2003 IIS 6.0中配置PHP的运行环境(图)
    sql语句跨服务器跨数据库执行
    ASP语法
    web 中 common
    common js
    经典的SQL面试题
    asp:TextBox 的ReadOnly属性 造成后台无法取到值
  • 原文地址:https://www.cnblogs.com/jiangjing/p/2943024.html
Copyright © 2011-2022 走看看