第三月光吧 关注:30贴子:2,177
  • 7回复贴,共1

终于把线段树的Lazy调过了......

只看楼主收藏回复

竟然只是一个小错误...害我调了1个月的时间


IP属地:广东1楼2012-06-11 22:46回复
    #include<iostream>
    #include<fstream>
    #define MAXN 500000
    #define MAX(a,b) (a>b ? a:b)
    #define cin fin
    #define cout fout
    using namespace std;
    ifstream fin("max1.in");
    ofstream fout("max1.out");
    struct SEG{
    int beg;
    int end;
    int mark;
    int maxv;
    } t[MAXN];
    int n,m,glen;
    int a[MAXN];
    void build(int v,int l,int r)
    {
    t[v].beg=l;
    t[v].end=r;
    t[v].mark=0;
    if(l==r)
    {
    t[v].maxv=a[l];
    return;
    }
    build(2*v,l,(l+r)/2);
    build(2*v+1,(l+r)/2+1,r);
    t[v].maxv=MAX(t[2*v].maxv,t[2*v+1].maxv);
    }
    int ask(int v,int l,int r)
    {
    if(t[v].beg==l&&t[v].end==r) return t[v].maxv;
    else
    {
    int mid=(t[v].beg+t[v].end)/2;
    if(r<=mid) return ask(2*v,l,r);
    else if(l>mid) return ask(2*v+1,l,r);
    else return MAX(ask(2*v,l,mid),ask(2*v+1,mid+1,r));
    }
    }
    int asks(int v,int l,int r)
    {
    t[2*v].mark+=t[v].mark,t[2*v].maxv+=t[v].mark;
    t[2*v+1].mark+=t[v].mark,t[2*v+1].maxv+=t[v].mark;
    t[v].mark=0;
    if(t[v].beg==l&&t[v].end==r) return t[v].maxv;
    else
    {
    int mid=(t[v].beg+t[v].end)/2;
    if(r<=mid) return asks(2*v,l,r);
    else if(l>mid) return asks(2*v+1,l,r);
    else return MAX(asks(2*v,l,mid),asks(2*v+1,mid+1,r));
    }
    }
    void change(int v,int i,int x)
    {
    if(t[v].beg==t[v].end)
    {
    t[v].maxv=x;
    return;
    }
    if(i>=t[2*v].beg&&i<=t[2*v].end) change(2*v,i,x);
    if(i>=t[2*v+1].beg&&i<=t[2*v+1].end) change(2*v+1,i,x);
    t[v].maxv=MAX(t[2*v].maxv,t[2*v+1].maxv);
    }
    void changes(int v,int l,int r,int x)
    {
    if(t[v].beg==l&&t[v].end==r) t[v].mark+=x,t[v].maxv+=x;
    else
    {
    t[2*v].mark+=t[v].mark,t[2*v].maxv+=t[v].mark;
    t[2*v+1].mark+=t[v].mark,t[2*v+1].maxv+=t[v].mark;
    t[v].mark=0;
    int mid=(t[v].beg+t[v].end)/2;
    if(r<=mid) changes(2*v,l,r,x);
    else if(l>mid) changes(2*v+1,l,r,x);
    else
    {
    changes(2*v ,l,mid,x);
    changes(2*v+1,mid+1,r,x);
    }
    t[v].maxv=MAX(t[2*v].maxv,t[2*v+1].maxv);
    }
    }
    int main()
    {
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
    cin>>m;
    for(int i=1;i<=m;i++)
    {
    int tag,q,p,k;
    cin>>tag;
    glen=0;
    if(tag==1)
    {
    cin>>q>>p>>k;
    glen=0;
    changes(1,q,p,k);
    }
    else if(tag==2)
    {
    cin>>q>>p;
    cout<<asks(1,q,p)<<endl;
    }
    else cout<<"What a ****!"<<endl;
    }
    return 0;
    }


    IP属地:广东3楼2012-06-11 22:48
    回复
      凑合看吧...题目如下...
      【题目描述】
      在N(1<=N<=100000)个数A1…An组成的序列上进行M(1<=M<=100000)次操作,操作有两种:
      (1)1 L R C:表示把A[L]到A[R]增加C(C的绝对值不超过10000);
      (2)2 L R:询问A[L]到A[R]之间的最大值。
      【输入】
      第一行输入N(1<=N<=100000),表示序列的长度,接下来N行输入原始序列;接下来一行输入M(1<=M<=100000)表示操作的次数,接下来M行,每行为1 L R C或2 L R
      【输出】
      对于每个操作(2)输出对应的答案。
      【样例输入】
      5
      1
      2
      3
      4
      5
      3
      2 1 4
      1 1 3 3
      2 3 5
      【样例输出】
      4
      6
      【限制】
      保证序列中的所有的数都在longint范围内


      IP属地:广东4楼2012-06-11 22:49
      回复
        哦擦,完全看不懂
        3RD好厉害!


        IP属地:福建5楼2012-06-11 23:00
        回复
          哦...话说我突然忘了你哪年高考来着


          IP属地:广东6楼2012-06-11 23:15
          回复
            消息现在才提示我...
            我是10年高考的啊
            


            IP属地:福建7楼2012-06-12 13:09
            回复
              不懂。。


              IP属地:江苏来自Android客户端8楼2012-06-12 17:09
              回复