NOIP11.15模拟 T2 三部曲

来源:互联网 发布:java.util.date怎么用 编辑:程序博客网 时间:2024/05/29 16:56

。。没想到正解,大概知道是线段树,但是不知道怎么处理,出来才知道是用dfs序,也有dalao用树剖怒艹。。然而我明明打的50分结果只有30分,A了之后看了一下别人50分的做法。。感觉我就算是暴力都打的很复杂。。有很多可以简化的东西。。要学习一下。
简洁的50分做法(来自hhh)

#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>#define ll long longusing namespace std;const char* fin="truetears.in";const char* fout="truetears.out";const int inf=0x7fffffff;const int maxn=50007,maxm=maxn*2;int n,m,i,j,k;int fi[maxn],ne[maxm],la[maxm],tot;ll a[maxn],ans;int fa[maxn];char ch;void add_line(int a,int b){    tot++;    ne[tot]=fi[a];    la[tot]=b;    fi[a]=tot;}void add(int v,int from,int ad){    int i,j,k;    a[v]+=ad;    for (k=fi[v];k;k=ne[k])        if (la[k]!=from){            add(la[k],v,ad+1);        }}void getans(int v,int from){    int i,j,k;    ans+=a[v];    for (k=fi[v];k;k=ne[k])        if (la[k]!=from) getans(la[k],v);}int main(){    freopen(fin,"r",stdin);    freopen(fout,"w",stdout);    scanf("%d%d",&n,&m);    for (i=2;i<=n;i++){        scanf("%d",&j);        fa[i]=j;        add_line(j,i);        add_line(i,j);    }    scanf("\n");    for (i=1;i<=m;i++){        scanf("%c%d",&ch,&j);        if (ch=='A'){            scanf("%d\n",&k);            add(j,fa[j],k);        }else{            scanf("\n");            ans=0;            getans(j,fa[j]);            cout<<ans<<endl;        }    }    return 0;}

当然还有我的满分做法:

var    i,j,k,p,n,m,tot,id,x,y:longint;    dfn,size,dep,fa,tmp:array[0..50010]of longint;    head,go,next:array[0..200000]of longint;    sum:Array[0..200000]of int64;    ds,siz:array[0..200000]of longint;    tag:array[0..200000,0..2]of longint;        ch:char;procedure add(x,y:longint);begin    inc(tot);    go[tot]:=y;    next[tot]:=head[x];    head[x]:=tot;end;procedure dfs(x:longint);var    i,v:longint;begin    inc(id);    dfn[x]:=id;    tmp[id]:=dep[x];    size[x]:=1;    i:=head[x];    while i<>0 do    begin        v:=go[i];        dep[v]:=dep[x]+1;        dfs(v);                size[x]:=size[x]+size[v];        i:=next[i];    end;end;procedure build(x,l,r:longint);var    mid:longint;begin    if (l=r) then    begin        siz[x]:=1;        ds[x]:=tmp[l];        exit;    end;    mid:=(l+r)div 2;    build(x*2,l,mid);    build(x*2+1,mid+1,r);    siz[x]:=siz[x*2]+siz[x*2+1];    ds[x]:=ds[x*2]+ds[x*2+1];end;procedure addd(x,x1,x2:longint);begin    sum[x]:=sum[x]+x1*siz[x]+x2*ds[x];    tag[x,0]:=tag[x,0]+x1;    tag[x,1]:=tag[x,1]+x2;end;procedure update(x:longint);begin    sum[x]:=sum[x*2]+sum[x*2+1];end;procedure clear(x,l,r:longint);var    mid:longint;begin    if (l<>r)and((tag[x,0]<>0)or(tag[x,1]<>0))then    begin        addd(x*2,tag[x,0],tag[x,1]);        addd(x*2+1,tag[x,0],tag[x,1]);        tag[x,0]:=0;        tag[x,1]:=0;    end;end;procedure modify(x,l1,r1,l,r,z:longint);var    mid:longint;begin    clear(x,l,r);    if (l1=l)and(r1=r) then    begin        addd(x,z,1);        clear(x,l,r);        exit;    end;    mid:=(l+r)div 2;    if r1<=mid then modify(x*2,l1,r1,l,mid,z)    else if mid+1<=l1 then modify(x*2+1,l1,r1,mid+1,r,z)    else    begin        modify(x*2,l1,mid,l,mid,z);        modify(x*2+1,mid+1,r1,mid+1,r,z);    end;    update(x);end;function query(x,l1,r1,l,r:longint):int64;var    mid:longint;begin    clear(x,l,r);    if (r1=r)and(l1=l) then exit(sum[x]);    mid:=(l+r)div 2;    if r1<=mid then exit(query(x*2,l1,r1,l,mid))    else if mid+1<=l1 then exit(query(x*2+1,l1,r1,mid+1,r))    else begin        exit(query(x*2,l1,mid,l,mid)+query(x*2+1,mid+1,r1,mid+1,r));    end;end;begin         assign(input,'truetears.in');        assign(output,'truetears.out');        reset(input);        rewrite(output);    readln(n,m);    for i:=2 to n do    begin        read(fa[i]);        add(fa[i],i);    end;    readln;    dep[1]:=1;    fa[1]:=0;    dfs(1);    build(1,1,n);    for i:=1 to m do    begin        read(ch);        if ch='Q' then        begin            readln(x);            writeln(query(1,dfn[x],dfn[x]+size[x]-1,1,id));        end        else begin            readln(x,y);            modify(1,dfn[x],dfn[x]+size[x]-1,1,id,y-dep[x]);        end;    end;end.
0 0
原创粉丝点击