现在的位置: 首页 > 综合 > 正文

zkw线段树修正 标记上升

2013年02月28日 ⁄ 综合 ⁄ 共 3766字 ⁄ 字号 评论关闭

今天才发现统计的力量很坑爹,同时发现了我写线段树的漏洞。

首先说我自己的问题,线段树最后一层的第一个节点不能用,但我以前用了而且一直没出问题,这次涉及区间修改才出现问题。

然后是统计的力量,里面关于区间修改,区间查询最大值的代码有bug,不但修改上传标记与查询回收标记一个是求最小值的,一个是最大值的,而且标记上传也不完全,查询时不能改开区间等等问题,幸亏有奥特曼的程序,否则我一直调不出。

值得一提的是,zkw这种标记上传,差分思想确实很厉害。

ps:网上几乎找不到这种zkw线段树做动态修改的rmq问题的程序

{$M 1000000000}
uses math;
var m1,n,ans,s,ss,m:longint;
    l,r,tail:array[1..1000000]of longint;
    t:array[0..2621440]of longint;
    next,sora:array[1..6000000]of longint;
procedure inf;
begin
 assign(input,'river.in');reset(input);
 assign(output,'river.out');rewrite(output)
end;
procedure ouf;
begin
 close(input);close(output)
end;
procedure origin;
var i:longint;
begin
 m1:=1;
 while m1<n<<1+3 do m1:=m1<<1;
 for i:=1 to n do tail[i]:=i;ss:=n
end;
procedure link(x,y:longint);
begin
 inc(ss);next[tail[x]]:=ss;tail[x]:=ss;sora[ss]:=y;
 inc(ss);next[tail[y]]:=ss;tail[y]:=ss;sora[ss]:=x
end;
procedure dfs(x,y:longint);
var i,ne:longint;
begin
 inc(s);l[x]:=s;
 i:=x;
 while next[i]<>0 do begin
  i:=next[i];ne:=sora[i];
  if ne<>y then dfs(ne,x)
 end;
 inc(s);r[x]:=s
end;
procedure change(l,r,x:longint);
var a:longint;
begin
 l:=l+m1-1;r:=r+m1+1;
 while not(l xor r=1) do begin
  if l and 1=0 then inc(t[l+1],x);
  if r and 1=1 then inc(t[r-1],x);
  a:=max(t[l],t[l xor 1]);dec(t[l],a);dec(t[l xor 1],a);inc(t[l>>1],a);
  a:=max(t[r],t[r xor 1]);dec(t[r],a);dec(t[r xor 1],a);inc(t[r>>1],a);
  l:=l>>1;r:=r>>1
 end;
 while l<>1 do begin
  a:=max(t[l],t[l xor 1]);
  if a<>0 then begin dec(t[l],a);dec(t[l xor 1],a);inc(t[l>>1],a) end
  else l:=2;
  l:=l>>1;
 end;
end;
function ask(l,r:longint):longint;
var lans,rans:longint;
begin
// if l=r then exit(t[l+m1]);
 l:=l+m1;r:=r+m1;lans:=0;rans:=0;
 while not(l xor r=1) do begin
  inc(lans,t[l]);inc(rans,t[r]);
  if l and 1=0 then lans:=max(lans,t[l+1]);
  if r and 1=1 then rans:=max(rans,t[r-1]);
  l:=l>>1;r:=r>>1
 end;
 ask:=max(lans+t[l],rans+t[r]);
 l:=l>>1;
 while l>0 do begin
  ask:=ask+t[l];
  l:=l>>1;
 end
end;
procedure init;
var i,j,k,x,y:longint;
    ch:char;
begin
 readln(n,m);
 origin;
 for i:=1 to n do begin
  read(x,j);
  for j:=1 to j do begin
   read(k);
   link(x,k)
  end;
  readln
 end;
 fillchar(t,sizeof(t),0);s:=0;
 dfs(1,0);
 for i:=1 to m do begin
  read(ch);
  if ch='P' then begin
   readln(x);
   ans:=ask(l[x],r[x]);
   writeln(max(ans,0))
  end
  else if ch='A' then begin
   readln(x,y);
   change(l[x],r[x],y)
  end
  else if ch='D' then begin
   readln(x,y);
   change(l[x],r[x],-y)
  end
 end
end;
begin
 inf;
 init;
 ouf
end.

c++版

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const int oo=1073741819;
long long n,m,ss,m1,len,ans;
long long b[1048576+5],tail[500000+5],next[500000+5],sora[500000+5],l[500000+5],r[500000+5];
//int b[524+5],tail[100+5],next[200+5],sora[200+5],l[100+5],r[100+5];

void origin()
{
     int i;
     ss=n;
     for (i=1;i<=n;i++)
      tail[i]=i;
     m1=1;
     for (;m1<=(n<<1)+2;) 
      m1<<=1;
}

void link(int x,int y)
{
     ss++;next[tail[x]]=ss;tail[x]=ss;sora[ss]=y;
//     ss++;next[tail[y]]=ss;tail[y]=ss;sora[ss]=x;
 }

void dfs(int x)
{
     int i,ne;
     len++;l[x]=len;
     for (i=x;next[i]!=0;)   
     {
         i=next[i],ne=sora[i];
         dfs(ne);
     }
     len++;r[x]=len;
 }

int max(long long x,long long y)
{
    return (x>y) ?  x : y;
}

void add(int l,int r,long long w)
{
     int k=0;
     for (l +=m1-1,r +=m1+1;!((l^r)==1);l>>=1,r>>=1)
     {
         if ((l&1)==0) b[l+1]+=w;
         if ((r&1)==1) b[r-1]+=w;
         k=max(b[l],b[l^1]);b[l]-=k;b[l^1]-=k;b[l>>1]+=k;
         k=max(b[r],b[r^1]);b[r]-=k;b[r^1]-=k;b[r>>1]+=k;
     }
     for (;l!=1;l>>=1)
     {
         k=max(b[l],b[l^1]);b[l]-=k;b[l^1]-=k;b[l>>1]+=k;
     }
 }

int ask(int l,int r)
{
    long long ans=-oo,lans=0,rans=0;
    for (l+=m1,r+=m1;!((l^r)==1);l>>=1,r>>=1)
    {
       lans+=b[l],rans+=b[r];
       if ((l&1)==0) lans=max(lans,b[l+1]);
       if ((r&1)==1) rans=max(rans,b[r-1]);
    }
    ans=max(lans+b[l],rans+b[r]);
    for (l>>=1;l;l>>=1)
      ans+=b[l];
    return ans;
}

void init()
{
     int i,j,x,k,y;
     char ch,ch1;
     scanf("%d%d",&n,&m);
     origin();
     for (i=1;i<=n;i++)
     {
         scanf("%d%d",&x,&k);
         for (j=1;j<=k;j++)
         {
             scanf("%d",&y);
             link(x,y);
         }         
         scanf("\n");
     }
     memset(b,0,sizeof(b));
     len=0;
     dfs(1);
     for (i=1;i<=m;)
     {
         scanf("%c",&ch);
         if (ch=='A') 
         {
                     scanf("%d%d\n",&x,&k);
                     add(l[x],r[x],k);
         }
         else if (ch=='D')
         {
              scanf("%d%d\n",&x,&k);
              add(l[x],r[x],-k);
          }
          else if (ch=='P')
          {
               scanf("%d\n",&x);
               ans=ask(l[x],r[x]);
               printf("%d\n",max(ans,0));
           }
         i++;
     }
}
int main()
{
    freopen("river.in","r",stdin);
    freopen("river.out","w",stdout);
    init();
    return 0;
}

抱歉!评论已关闭.