HDU 4614 线段树+二分

一开始做用自己的方法,一直WA,自己也出不出错误的例子,放弃了自己的代码,看了一下别人的方法都是线段树+二分,逻辑很清晰,也很好写,基本就是板子。

#include 
#include 
#include 
#include 
using namespace std;
struct node
{
    int sum,lz;
}a[50005 << 3];
void build(int d, int l, int r)
{
    a[d].sum = r - l + 1; a[d].lz = -1;
    if(l == r) return;
    int m = (l+r) >> 1;
    build(d*2,l,m); build(d*2+1,m+1,r);
}
void pushup(int d)
{
    a[d].sum = a[d*2].sum + a[d*2 + 1].sum;
}
void pushdown(int d, int l, int r)
{
    if(a[d].lz != -1)
    {
        int m = (l+r) >> 1;
        int ld = d*2, rd = ld + 1;
        a[ld].lz = a[rd].lz = a[d].lz;
        a[ld].sum = (m - l + 1)*a[d].lz;
        a[rd].sum = (r - m)*a[d].lz;
        a[d].lz = -1;
    }
}
int query(int d, int l, int r, int ql, int qr)
{
    if(ql <= l && r <= qr)
    {
        return a[d].sum;
    }
    int m = (l+r) >> 1;
    int ans = 0;
    pushdown(d,l,r);
    if(ql <= m) ans += query(d*2,l,m,ql,qr);
    if(m < qr) ans += query(d*2+1,m+1,r,ql,qr);
    return ans;
}
int query_0(int d, int l, int r, int ql, int qr)
{
    if(ql <= l && r <= qr)
    {
        return r - l +1  - a[d].sum;
    }
    int m = (l+r) >> 1; int ans = 0;
    pushdown(d,l,r);
    if(ql <= m) ans += query_0(d*2,l,m,ql,qr);
    if(m < qr) ans += query_0(d*2+1,m+1,r,ql,qr);
    return ans;
}
void update(int d, int l, int r, int ql, int qr, int c)
{
    if(ql <= l && r <= qr)
    {
        a[d].lz = c;
        a[d].sum = (r - l + 1)*c;
        return;
    }
    pushdown(d,l,r);
    int m = (l +r) >> 1;
    if(ql <= m) update(d*2,l,m,ql,qr,c);
    if(m < qr)update(d*2+1,m+1,r,ql,qr,c);
    pushup(d);
    return;
}
int main()
{
    int n,m;
    int times; cin >> times;
    while(times --)
    {
        scanf("%d%d",&n,&m);
        build(1,1,n);
        while(m -- )
        {
            int k,x,y;
            scanf("%d%d%d",&k,&x,&y);
            if(k == 1)
            {
                int t = query(1,1,n,x+1,n);
                if(t == 0)
                {
                    printf("Can not put any one.\n");
                    continue;
                }
                int lsum = 0;
                if(x != 0)
                lsum = query(1,1,n,1,x);
                lsum ++;
                //cout <<"   ff " <> 1;
                    nows = query(1,1,n,l,m);
                    //cout << l << "    " <= lsum) r = m;
                    else if(nows < lsum)
                    {
                         lsum -= nows;
                         l = m + 1;
                    }
                }
                lp = l;
                int rsum = min(y,t); l = lp,r = n;
                  while(l < r)
                {
                    m = (l+r) >> 1;
                    nows = query(1,1,n,l,m);
                   // cout << l <<"    " <= rsum) r = m;
                    else if(nows < rsum)
                    {
                         rsum -= nows;
                         l = m + 1;
                    }
                }
                int rp = l;
                printf("%d %d\n",lp- 1,rp-1);
                update(1,1,n,lp,rp,0);
            }
            else
            {
                printf("%d\n",query_0(1,1,n,x+1,y+1));
                update(1,1,n,x+1,y+1,1);
            }
        }
        printf("\n");
    }
}

——————————————————————————————————————————————————分割线


顺便贴一下WA的代码,没有找出来哪里错了

#include 
#include 
#include 
#include 
#pragma comment(linker, "/STACK:36777216")
using namespace std;
struct node
{
    int sum,st,en;
    int lz;
}a[50010<<4];
void build(int d,int l, int r)
{
   int len = r - l + 1;
   a[d].sum = len; a[d].st = l,a[d].en = r;
   a[d].lz = -1;
   if(l == r)  return;
   int m = (l+r)>>1;
   build(d*2,l,m);
   build(d*2+1,m+1,r);
   return;
}

void pushup(int d)
{
    int ld = d*2,rd = d*2 +1;
    a[d].sum = a[ld].sum + a[rd].sum;
    if(a[d].sum == 0) return;
    if(a[ld].sum != 0) a[d].st = a[ld].st;
    else a[d].st = a[rd].st;
    if(a[rd].sum != 0) a[d].en = a[rd].en;
    else a[d].en = a[ld].en;
    return ;
}
void push1(int d, int l, int r)
{
     if(a[d].sum == r - l +1 && a[d].lz == 0)
     {
         int ld = 2*d, rd = 2*d + 1;
         int m = (l+r)>>1;
         a[ld].sum = m - l +1; a[rd].sum = r - m;
         a[ld].st = l, a[ld].en = m;
         a[rd].st = m+1, a[rd].en = r;
         a[d].lz = -1;
         a[ld].lz = 0, a[rd].lz = 0;
     }
     return;
}
int al,ar,s,ts;
void pushdown(int d , int l, int r)
{
    
    //cout << l << " pp    " <> 1;int ld = d*2, rd = ld + 1;
     if(a[ld].sum && s)pushdown(ld,l,m);
     if(a[rd].sum && s)pushdown(rd,m+1,r);
     pushup(d);
    }
}
void push0(int d, int l, int r)
{
    if(a[d].sum == 0 && a[d].lz == 1)
    {
         a[d].lz = -1;
         int ld = 2*d, rd = 2*d + 1;
         int m = (l+r)>>1;
         a[ld].sum = 0; a[rd].sum = 0;
         a[ld].lz = 1; a[rd].lz = 1;
    }
}
void query(int d, int l, int r, int t)
{
    if(l  == t)
    {
    //cout << l <<"    "<< r <<"    "< s)
        {
            if(s == ts) al = a[d].st;
            pushdown(d,l,r);
        }
        else if(a[d].sum <= s)
        {
            if(s== ts) al = a[d].st;
            s -= a[d].sum; ar = a[d].en; a[d].lz = 1;
            a[d].sum = 0;
        }
        return ;
    }

    push1(d,l,r);
    int m = (l+r) >>1;
    //cout << l << "     " << r <<"    " << a[d].sum <<"   "< 0 && a[d*2+1].sum) query(d*2+1,m+1,r,max(t,m+1));
    pushup(d);
}
int update(int d, int l, int r ,int ql, int qr)
{
    int ans = 0;
    if(ql <= l && r <= qr)
    {
        ans =r - l+ 1 -  a[d].sum;
        //cout << l <<" gg  " <>1;
    if(ql <= m) ans += update(d*2,l,m,ql,qr);
    if(m < qr) ans += update(d*2+1,m+1,r,ql,qr);
    pushup(d);
    return ans;
}
int main()
{
    int times,n,m,op;
    scanf("%d",×);
    while(times --)
    {
        int x,y;
        scanf("%d%d",&n,&m);
        build(1,1,n);
        while(m --)
        {
            scanf("%d%d%d",&op,&x,&y);
            if(op == 1)
            {
                s = y;ts = y; x += 1;
              //  cout << n <<"   "<< x<< endl;
                query(1,1,n,x);
              if(s < y)
               printf("%d %d\n",al -1,ar - 1);
              else
                printf("Can not put any one.\n");
            }
            else
            {
                printf("%d\n",update(1,1,n,x+1,y+1));
            }
        }
        printf("\n");
    }
}




你可能感兴趣的:(HDU 4614 线段树+二分)