hdu4605 线段树+dfs

来源:互联网 发布:盗梦侦探红辣椒 知乎 编辑:程序博客网 时间:2024/05/22 11:52

dfs树节点,同时用线段树记录左右节点路径。


ACcode:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<vector>#include<cstdlib>using namespace std;#pragma comment(linker,"/STACK:102400000,102400000")#define lc rt<<1#define rc rt<<1|1#define now seg[rt]const int NS=111111;struct node{    int val;    int lch,rch;}ball[NS];struct line{    int id,val;};struct answer{    int x,y;}ans[NS];struct segment{    int lft,rgt;    int num[2];}seg[NS<<2];int n,m,q;int w[NS];int sum,numl,numr,flag,top;vector<line> qur[NS];void init(){    top=1,sum=0;    for (int i=0;i<=n;i++)    qur[i].clear();}void build(int rt,int lft,int rgt){    now.num[0]=now.num[1]=0;    now.lft=lft,now.rgt=rgt;    if (lft==rgt) return ;    int mid=(lft+rgt)>>1;    build(lc,lft,mid);    build(rc,mid+1,rgt);}void update(int rt,int dir,int add,int val){    now.num[dir]+=add;    if (now.lft==now.rgt) return ;    int mid=(now.lft+now.rgt)>>1;    if (w[mid]>=val)        update(lc,dir,add,val);    else        update(rc,dir,add,val);}void query(int rt,int val){    if (val<w[now.lft])        return ;    if (val>w[now.rgt])    {        numl+=now.num[0];        numr+=now.num[1];        return ;    }    if (now.lft==now.rgt)    {        flag +=now.num[0]+now.num[1];        return ;    }    query(lc,val);    query(rc,val);}void dfs(int rt){    for (int i=0;i<qur[rt].size();i++)    {        answer tmp;        int val=qur[rt][i].val;        int id=qur[rt][i].id;        numl=numr=flag=0;        query(1,val);        if (flag) tmp.x=-1;        else        {            tmp.x=numr;            tmp.y=sum+2*(numl+numr);        }        ans[id]=tmp;    }    if (ball[rt].lch<0) return ;    update(1,0,1,ball[rt].val),sum++;    dfs(ball[rt].lch);    update(1,0,-1,ball[rt].val),sum--;    update(1,1,1,ball[rt].val),sum++;    dfs(ball[rt].rch);    update(1,1,-1,ball[rt].val),sum--;}int main(){    int T;    for (scanf("%d",&T);T;T--)    {        scanf("%d",&n);        init();        for (int i=1;i<=n;i++)        {            scanf("%d",&w[i]);            ball[i].val=w[i];            ball[i].lch=-1;            ball[i].rch=-1;        }        sort(w+1,w+n+1);        for (int i=2;i<=n;i++)        if (w[i]!=w[i-1])            w[++top]=w[i];        build(1,1,top);        for (scanf("%d",&m);m;m--)        {            int u,l,r;            scanf("%d %d %d",&u,&l,&r);            ball[u].lch=l,ball[u].rch=r;        }        scanf("%d",&q);        for (int i=0;i<q;i++)        {            int v,x;            line tmp;            scanf("%d %d",&v,&x);            tmp.id=i,tmp.val=x;            qur[v].push_back(tmp);            if (v==1)            ans[i].x=ans[i].y=0;        }        if(ball[1].lch>=0)        {            update(1,0,1,ball[1].val),sum++;            dfs(ball[1].lch);            update(1,0,-1,ball[1].val),sum--;            update(1,1,1,ball[1].val),sum++;            dfs(ball[1].rch);            update(1,1,-1,ball[1].val),sum--;        }        for (int i=0;i<q;i++)        if (ans[i].x<0)            printf("0\n");        else            printf("%d %d\n",ans[i].x,ans[i].y);    }    return 0;}


原创粉丝点击