3631: [JLOI2014]松鼠的新家|树链剖分

来源:互联网 发布:与喝酒有关的网络红歌 编辑:程序博客网 时间:2024/03/29 12:36

题目大意:小熊每走到一个新的房间就需要吃一个糖,问每个房间至少有几个糖。
题目中说的很不明确的样子。。。。。。
枚举相邻的两个点,把这连接这两个点的链上的点的权值都+1,然后除了起点外其他的点都再-1
可以直接树剖线段树直接标记改,复杂度O(nlog22n)
也可以直接差分一下最后在dfs一遍,复杂度O(nlog2n)
code1线段树:

#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<queue>#include<vector>#include<set>#include<map>#include<iostream>#include<algorithm>#define ll unsigned long long#define N 300022#define mx 1e9using namespace std;int sc(){    int i=0,f=1; char c=getchar();    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}    while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();    return i*f;}int head[N],lst[N*2],nxt[N*2];int tag[N*4],ans[N],a[N];int size[N],fa[N],top[N],deep[N],S[N];int n,tot,cnt,TI;void insert(int x,int y){    lst[++tot]=y;nxt[tot]=head[x];head[x]=tot;    lst[++tot]=x;nxt[tot]=head[y];head[y]=tot;}void dfs(int x,int f){    for(int i=head[x];i;i=nxt[i])        if(lst[i]!=f)        {            fa[lst[i]]=x;            deep[lst[i]]=deep[x]+1;            dfs(lst[i],x);            size[x]+=size[lst[i]];        }    size[x]++;}void _dfs(int x,int htp){    top[x]=htp;S[x]=++cnt;    int k=0;    for(int i=head[x];i;i=nxt[i])        if(lst[i]!=fa[x]&&size[lst[i]]>size[k])k=lst[i];    if(!k)return;_dfs(k,htp);    for(int i=head[x];i;i=nxt[i])        if(lst[i]!=fa[x]&&lst[i]!=k)            _dfs(lst[i],lst[i]);}void push_down(int x){    if(tag[x])    {        tag[x<<1]+=tag[x];        tag[x<<1|1]+=tag[x];        tag[x]=0;    }}void modify(int x,int L,int R,int l,int r){    if(L==l&&R==r){tag[x]++;return;}    push_down(x);    int mid=L+R>>1;    if(r<=mid)modify(x<<1,L,mid,l,r);    else if(l>mid)modify(x<<1|1,mid+1,R,l,r);    else modify(x<<1,L,mid,l,mid),modify(x<<1|1,mid+1,R,mid+1,r);}void change(int x,int y){    while(top[x]!=top[y])    {        if(deep[top[x]]<deep[top[y]])swap(x,y);        modify(1,1,n,S[top[x]],S[x]);        x=fa[top[x]];    }    if(deep[x]>deep[y])swap(x,y);    modify(1,1,n,S[x],S[y]);}int ask(int x,int l,int r,int p){    if(l==p&&r==p)return tag[x];    push_down(x);    int mid=l+r>>1;    if(p<=mid)return ask(x<<1,l,mid,p);    else return ask(x<<1|1,mid+1,r,p);}int main(){    n=sc();    for(int i=1;i<=n;i++)a[i]=sc();    for(int i=1;i<n;i++)    {        int x=sc(),y=sc();        insert(x,y);    }    dfs(1,0);_dfs(1,1);    for(int i=1;i<n;i++)        change(a[i],a[i+1]);    for(int i=1;i<=n;i++)    {        ans[i]=-(i!=a[1]);        ans[i]+=ask(1,1,n,S[i]);    }    for(int i=1;i<=n;i++)        printf("%d\n",ans[i]);    return 0;}

code2差分:

#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<queue>#include<vector>#include<set>#include<map>#include<iostream>#include<algorithm>#define ll unsigned long long#define N 300022#define mx 1e9using namespace std;int sc(){    int i=0,f=1; char c=getchar();    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}    while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();    return i*f;}int head[N],lst[N*2],nxt[N*2];int tag[N*4],ans[N],a[N],v[N];int size[N],fa[N],top[N],deep[N],S[N];int n,tot,cnt,TI;void insert(int x,int y){    lst[++tot]=y;nxt[tot]=head[x];head[x]=tot;    lst[++tot]=x;nxt[tot]=head[y];head[y]=tot;}void dfs(int x,int f){    for(int i=head[x];i;i=nxt[i])        if(lst[i]!=f)        {            fa[lst[i]]=x;            deep[lst[i]]=deep[x]+1;            dfs(lst[i],x);            size[x]+=size[lst[i]];        }    size[x]++;}void _dfs(int x,int htp){    top[x]=htp;S[x]=++cnt;    int k=0;    for(int i=head[x];i;i=nxt[i])        if(lst[i]!=fa[x]&&size[lst[i]]>size[k])k=lst[i];    if(!k)return;_dfs(k,htp);    for(int i=head[x];i;i=nxt[i])        if(lst[i]!=fa[x]&&lst[i]!=k)            _dfs(lst[i],lst[i]);}int Lca(int x,int y){    while(top[x]!=top[y])    {        if(deep[top[x]]<deep[top[y]])swap(x,y);        x=fa[top[x]];    }    return deep[x]>deep[y]?y:x;}void __dfs(int x,int f){    for(int i=head[x];i;i=nxt[i])        if(lst[i]!=f)        {            __dfs(lst[i],x);            v[x]+=v[lst[i]];        }    ans[x]+=v[x];}int main(){    n=sc();    for(int i=1;i<=n;i++)a[i]=sc();    for(int i=1;i<n;i++)    {        int x=sc(),y=sc();        insert(x,y);    }    dfs(1,0);_dfs(1,1);    for(int i=2;i<=n;i++)    {        int lca=Lca(a[i],a[i-1]);        ans[a[i]]=-1;        v[a[i-1]]+=1;v[a[i]]+=1;v[lca]-=1;v[fa[lca]]-=1;    }    __dfs(1,0);    for(int i=1;i<=n;i++)        printf("%d\n",ans[i]);    return 0;}
0 0
原创粉丝点击