[BZOJ3626] LCA - 离线 - 树链剖分/动态树/分块

来源:互联网 发布:相册软件哪个好 编辑:程序博客网 时间:2024/05/22 04:53

        大雾啊……BZOJ上是10s题到了我校OJ就成了100MS每点

        目测这是要写树剖+BIT的东西……窝LCT卡常数卡了好久都没艹过去,BZOJ都稳稳前两页了……

        好伐还是说题解吧…… 首先我们可以离线将所有回答排序。首先我们用前缀和思想,即Ans[l,r]=Ans[1,r]-Ans[1,l-1]

        然后我们可以发现,我们每次处理的就是对应的z关于1~a这么多点的LCA的深度之和。

        如果我们将一个点t到根节点连的路径上都加上一个权值1的话,显然dep(lca(t,z))就等于z到根路径上的权值和……

        然后就依次插入点然后乱搞搞了…… 不懂可以看黄学长博客TAT。

#include "stdio.h"#include "stdlib.h"#include "algorithm"#define rep(f,a,b) for(f=a;f<=b;f++)typedef long long ll;using namespace std;const int N=50005,M=2000000;const int MOD=201314,Q=50005;char buff[M+5],*__pos;void ReadIn(){fread(buff,sizeof(char),M,stdin);__pos=buff;}inline int read(){int x=0; char ch=*__pos;while(ch<'0'||ch>'9') ch=*(++__pos);while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=*(++__pos);}return x;}struct node{int tag,size,sum,val;node *fa,*c[2]; node();inline void push_up();inline void push_down();} Tnull, *null=&Tnull, v[N];node:: node(){fa=c[0]=c[1]=null;tag=size=sum=val=0;}inline void node:: push_up(){if(c[0]!=null) c[0]->push_down();if(c[1]!=null) c[1]->push_down();size=c[0]->size+c[1]->size+1;sum=c[0]->sum+c[1]->sum+val;if(c[0]!=null)c[0]->fa=this;if(c[1]!=null)c[1]->fa=this;}inline void node:: push_down(){if (tag){sum+=size*tag; val+=tag;if(c[0]!=null)c[0]->tag+=tag;if(c[1]!=null)c[1]->tag+=tag;tag=0;}}inline void rotate (node *x){node *y=x->fa,*z=y->fa;y->push_down(); x->push_down();if(z->c[0]==y) z->c[0]=x;if(z->c[1]==y) z->c[1]=x;int l=y->c[1]==x,r=l^1;x->fa=z; y->fa=x; y->c[l]=x->c[r];if(x->c[r]!=null)x->c[r]->fa=y;x->c[r]=y; y->push_up();x->push_up();}inline void splay (node *x){x->push_down();while (x->fa->c[0]==x||x->fa->c[1]==x){node *y=x->fa,*z=y->fa;if(y->fa->c[0]==y||y->fa->c[1]==y){if (z->c[0]==y ^ y->c[0]==x) rotate(x);else rotate(y);} rotate(x);}}inline void access (node *x){for (node *y=null; x!=null; y=x,x=x->fa)splay(x),x->c[1]=y,x->push_up();}typedef struct QueryAskData {int l,r,z,id;inline void init();} QAD; QAD quest[Q];inline void QAD:: init(){l=read(),r=read(),z=read();id=(int)(this- quest);l++,r++,z++;}typedef struct QuestAskDataSort{int tag,x,id,z;inline void ins(int _,int __,int ___,int ____);inline bool operator <(const QuestAskDataSort &a) const;} QADS; QADS data[2*Q];inline bool QADS:: operator <(const QADS&a) const{return x==a.x?id<a.id:x<a.x;}void QADS:: ins(int _,int __,int ___,int ____){ tag=_,z=__,id=___,x=____;}int ans[Q],n,q;int main(){ReadIn(); n=read(),q=read(); int i,t;rep(i,1,n)v[i].size=1;rep(i,2,n){t=read(); ++t;v[i].fa=v+t;}rep(i,1,q){quest[i].init(); if(quest[i].l==1) ++ans[i];data[2*i-1].ins(-1,quest[i].z,i,quest[i].l-1);data[2*i].ins(1,quest[i].z,i,quest[i].r);} sort(data+1,data+2*q+1); int j;for (i=j=1;j<=n;j++){access(v+j); splay(v+j); v[j].tag++;while (data[i].x<=j&&i<=2*q){access(v+data[i].z); splay(v+data[i].z);v[data[i].z].push_down();ans[data[i].id]+=v[data[i].z].sum*data[i].tag;i++;}} rep(i,1,q) printf("%d\n",ans[i]%MOD);return 0;}


0 0
原创粉丝点击