hdu5111
链接
hdu
hdu挂了,我也不知道这份代码对不对,反正过了对拍了
思路
先考虑序列上如何解决。
1 3 2 5 4 1 2 4 5 3
这个序列变成
1 2 3 4 5 1 3 5 5 2
是对答案没有影响的(显然)。
然后查询操作\(l,r,L,R\)就是,
一段连续的区间\([L,R]\)内包含几个值在\([l,r]\)的数字个数.
主席树就可以做了。
\(query(rt[L-1],rt[R],[l,r]的和)\)
可以用树链剖分把树上问题转化成链上。
左边一棵树树链剖分,每一条链子都是一段连续的。
右边一棵树根据父子关系建立主席树。
然后向上跳统计贡献。
错误
一遍过样例,然而清空死了。
而且这错误找了之后我也不感觉他错。
对,我感觉是c++的错。
代码
#include <iostream> #include <map> #include <cstring> #include <algorithm> #define ls(x) (t[x].ls) #define rs(x) (t[x].rs) using namespace std; const int _=1e5+7; int read() { int x=0,f=1;char s=getchar(); for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1; for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0'; return x*f; } int n1,n2,w1[_],w2[_],rt[_]; map<int,int> dsr; struct node { int v,nxt; }e1[_<<1],e2[_<<1]; int head1[_],head2[_],tot1,tot2; void add1(int u,int v) { e1[++tot1].v=v; e1[tot1].nxt=head1[u]; head1[u]=tot1; } void add2(int u,int v) { e2[++tot2].v=v; e2[tot2].nxt=head2[u]; head2[u]=tot2; } namespace ZXS { struct node { int ls,rs,tot; }t[_*30]; int cnt; void clear() { memset(t,0,sizeof(t)); // for(int i=0;i<=cnt;++i) // ls(i)=rs(i)=t[i].tot=0; cnt=0; } void insert(int l,int r,int k,int x,int &y) { t[y=++cnt]=t[x]; t[y].tot++; if(l==r) return; int mid=(l+r)>>1; if(k<=mid) insert(l,mid,k,ls(x),ls(y)); else insert(mid+1,r,k,rs(x),rs(y)); } int query(int l,int r,int L,int R,int x,int y) { if(L<=l&&r<=R) return t[y].tot-t[x].tot; int mid=(l+r)>>1,ans=0; if(L<=mid) ans+=query(l,mid,L,R,ls(x),ls(y)); if(R>mid) ans+=query(mid+1,r,L,R,rs(x),rs(y)); return ans; } } namespace LCA{ int siz[_],son[_],top[_],f[_],dep[_],idx[_],cnt; void clear() { cnt=0; memset(idx,0,sizeof(idx)); // memset(siz,0,sizeof(siz)); memset(son,0,sizeof(son)); // memset(top,0,sizeof(top)); // memset(dep,0,sizeof(dep)); // memset(f,0,sizeof(f)); } void dfs1(int u,int fa) { dep[u]=dep[fa]+1; f[u]=fa; siz[u]=1; for(int i=head2[u];i;i=e2[i].nxt) { int v=e2[i].v; if(v==fa) continue; dfs1(v,u); siz[u]+=siz[v]; if(siz[v]>siz[son[u]]) son[u]=v; } } void dfs2(int u,int topf) { idx[u]=++cnt; top[u]=topf; if(!son[u]) return; dfs2(son[u],topf); for(int i=head2[u];i;i=e2[i].nxt) { int v=e2[i].v; if(!idx[v]) dfs2(v,v); } } int query(int x,int y) { while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); x=f[top[x]]; } if(dep[x]>dep[y]) swap(x,y); return x; } } namespace SLPF{ int siz[_],son[_],top[_],f[_],dep[_],idx[_],cnt; void clear() { cnt=0; memset(idx,0,sizeof(idx)); // memset(siz,0,sizeof(siz)); memset(son,0,sizeof(son)); // memset(top,0,sizeof(top)); // memset(dep,0,sizeof(dep)); // memset(f,0,sizeof(f)); } void dfs1(int u,int fa) { dep[u]=dep[fa]+1; f[u]=fa; siz[u]=1; for(int i=head1[u];i;i=e1[i].nxt) { int v=e1[i].v; if(v==fa) continue; dfs1(v,u); siz[u]+=siz[v]; if(siz[v]>siz[son[u]]) son[u]=v; } } void dfs2(int u,int topf) { idx[u]=++cnt; dsr[w1[u]]=cnt; top[u]=topf; if(!son[u]) return; dfs2(son[u],topf); for(int i=head1[u];i;i=e1[i].nxt) { int v=e1[i].v; if(!idx[v]) dfs2(v,v); } } void QQ(int x,int y,int u2,int v2) { int lca=LCA::query(u2,v2),ans=0; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); ans+=ZXS::query(1,n1,idx[top[x]],idx[x],rt[lca],rt[u2]); // cout<<ZXS::query(1,n1,idx[top[x]],idx[x],rt[lca],rt[u2])<<"\n"; ans+=ZXS::query(1,n1,idx[top[x]],idx[x],rt[LCA::f[lca]],rt[v2]); // cout<<ZXS::query(1,n1,idx[top[x]],idx[x],rt[LCA::f[lca]],rt[v2])<<"\n"; x=f[top[x]]; } if(dep[x]>dep[y]) swap(x,y); ans+=ZXS::query(1,n1,idx[x],idx[y],rt[lca],rt[u2]); // cout<<ZXS::query(1,n1,idx[x],idx[y],rt[lca],rt[u2])<<"\n"; ans+=ZXS::query(1,n1,idx[x],idx[y],rt[LCA::f[lca]],rt[v2]); // cout<<ZXS::query(1,n1,idx[x],idx[y],rt[LCA::f[lca]],rt[v2])<<"\n"; printf("%d\n",ans); } } void dfs(int u,int fa) { if(dsr.count(w2[u])) ZXS::insert(1,n1,dsr[w2[u]],rt[fa],rt[u]); else rt[u]=rt[fa]; for(int i=head2[u];i;i=e2[i].nxt) { int v=e2[i].v; if(v==fa) continue; dfs(v,u); } } int main() { // freopen("data.in","r",stdin); // freopen("a.out","w",stdout); while(scanf("%d",&n1)!=EOF) { //clear LCA::clear(); SLPF::clear(); ZXS::clear(); dsr.clear(); tot1=tot2=0; memset(rt,0,sizeof(rt)); memset(head1,0,sizeof(head1)); memset(head2,0,sizeof(head2)); //read for(int i=2;i<=n1;++i) { int u=i,v=read(); // cout<<u<<"->"<<v<<"\n"; add1(u,v),add1(v,u); } for(int i=1;i<=n1;++i) w1[i]=read(); n2=read(); for(int i=2;i<=n2;++i) { int u=i,v=read(); // cout<<u<<"->"<<v<<"\n"; add2(u,v),add2(v,u); } for(int i=1;i<=n2;++i) w2[i]=read(); //init SLPF::dfs1(1,0); SLPF::dfs2(1,1); LCA::dfs1(1,0); LCA::dfs2(1,1); dfs(1,0); //ask int Q=read(); while(Q --> 0) { int u1=read(),v1=read(),u2=read(),v2=read(); SLPF::QQ(u1,v1,u2,v2); } } return 0; }