spoj Query on a tree3/bzoj 1803(DFS序+主席树)

来源:互联网 发布:中兴视觉大数据怎么样 编辑:程序博客网 时间:2024/06/05 09:18

传送门
题解:在DFS序上维护主席树,每次修改权值线段树上一条链,链底时记录一下对应的树上点的编号,然后按主席树第k大的方式查询即可。
P.S.经常迷之CE,就是在bzoj上AC的代码都要CE。。。在本地DEV-C++把警告提示开到最大都没出错。。。
“prog.cpp:8:17: error: too many decimal points in number

Apache/2.4.18 (Ubuntu) Server at ocs-pl.oktawave.com Port 80

prog.cpp:1:1: error: expected u”
后来发现MAXN不能写成1e5+4,要写成100004…(╯‵□′)╯︵┻━┻

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN=100004;int n,m,a[MAXN],b[MAXN];int head[MAXN],edge=0;struct EDGE {    int v,nxt;}e[MAXN<<1];int in[MAXN],out[MAXN],tim=0,tot=0;int root[MAXN],lc[MAXN*18],rc[MAXN*18],sum[MAXN*18],rk[MAXN*18];inline int read() {    int x=0,f=1;char c=getchar();    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}    while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();    return x*f;}inline void adde(int u,int v) {    e[++edge].nxt=head[u],e[edge].v=v,head[u]=edge;    e[++edge].nxt=head[v],e[edge].v=u,head[v]=edge;}void modify(int pre,int &rt,int l,int r,int val,int id) {    rt=++tot;    sum[rt]=sum[pre]+1;    if (l==r) {        rk[rt]=id;        return ;    }    lc[rt]=lc[pre],rc[rt]=rc[pre];    int mid=(l+r)>>1;    if (val<=mid) modify(lc[pre],lc[rt],l,mid,val,id);    else modify(rc[pre],rc[rt],mid+1,r,val,id);}int query(int pre,int rt,int l,int r,int k) {    if (l==r) return rk[rt];    int mid=(l+r)>>1,temp=sum[lc[rt]]-sum[lc[pre]];    if (k<=temp) return query(lc[pre],lc[rt],l,mid,k);    else return query(rc[pre],rc[rt],mid+1,r,k-temp);}void dfs(int p,int fa) {    in[p]=++tim;    modify(root[in[p]-1],root[in[p]],0,MAXN/*写100000迷之Compile Error*/,a[p],p);    for (int i=head[p];~i;i=e[i].nxt) {        int v=e[i].v;        if (v^fa)            dfs(v,p);    }    out[p]=tim;}int main() {//  freopen("spoj qot3.in","r",stdin);    memset(head,-1,sizeof(head));    n=read();    for (register int i=1;i<=n;++i) b[i]=a[i]=read();    sort(b+1,b+n+1);    int nn=unique(b+1,b+n+1)-b-1;    for (register int i=1;i<=n;++i) a[i]=lower_bound(b+1,b+nn+1,a[i])-b;    for (register int i=1;i<n;++i) {        int u=read(),v=read();        adde(u,v);    }    dfs(1,0);    m=read();    for (register int t=0;t^m;++t) {        int pos=read(),k=read();        printf("%d\n",query(root[in[pos]-1],root[out[pos]],0,MAXN,k));    }    return 0;}
阅读全文
0 0
原创粉丝点击