SPOJ COT2 Count on a tree II [树上莫队]
2017-03-18 15:45
375 查看
题意:
询问路径上多少种不同的点权
我一直写了假的莫队!!!!
正确的排序方式是$(pos[u],dfn[v])$,我却一直用原始点的编号排序!!!
然后你会发现代码中有一些卡常...
询问路径上多少种不同的点权
我一直写了假的莫队!!!!
正确的排序方式是$(pos[u],dfn[v])$,我却一直用原始点的编号排序!!!
然后你会发现代码中有一些卡常...
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; typedef long long ll; const int N=2e5+5; inline int read(){ char c=getchar();int x=0,f=1; 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; } int n,Q,a ,mp ,u,v; struct edge{int v,ne;} e[N<<1]; int cnt,h ; inline void ins(int u,int v){ e[++cnt]=(edge){v,h[u]}; h[u]=cnt; e[++cnt]=(edge){u,h[v]}; h[v]=cnt; } int block, pos , m, st , top; int fa [18], deep , dfn , dfc; void dfs(int u){ dfn[u]=++dfc; for(int i=1; (1<<i)<=deep[u]; i++) fa[u][i]=fa[ fa[u][i-1] ][i-1]; int bot=top; for(int i=h[u];i;i=e[i].ne) if(e[i].v!=fa[u][0]){ fa[e[i].v][0]=u; deep[e[i].v]=deep[u]+1; dfs(e[i].v); if(top-bot>=block){ m++; while(top!=bot) pos[st[top--]]=m; } } st[++top]=u; } inline int lca(int x,int y){ if(deep[x]<deep[y]) swap(x, y); int bin=deep[x]-deep[y]; for(int i=0;i<17;i++) if((1<<i)&bin) x=fa[x][i]; if(x==y) return x; for(int i=16;i>=0;i--) if(fa[x][i]!=fa[y][i]) x=fa[x][i], y=fa[y][i]; return x==y ? x : fa[x][0]; } struct meow{ int u, v, id; bool operator <(const meow &a) const {return pos[u]==pos[a.u] ? dfn[v]<dfn[a.v] : pos[u]<pos[a.u];} }q ; int vis , cou , now, ans ; inline void Xor(int u){ if(!vis[u]) now+= (++cou[a[u]])==1; else now-= (--cou[a[u]])==0; vis[u]^=1; } inline void move(int x,int y){ //printf("%d --> %d %d\n",x,y,now); if(deep[x]<deep[y]) swap(x, y); while(deep[x]>deep[y]) Xor(x), x=fa[x][0]; while(x!=y) Xor(x), Xor(y), x=fa[x][0], y=fa[y][0]; } void modui(){ u=1, v=1; for(int i=1;i<=Q;i++){ if(u!=q[i].u) move(u, q[i].u), u=q[i].u; if(v!=q[i].v) move(v, q[i].v), v=q[i].v; int anc=lca(u, v); ans[q[i].id]= now + (cou[a[anc]]==0); } } int main(){ freopen("in","r",stdin); n=read(); Q=read(); for(int i=1;i<=n;i++) a[i]=mp[i]=read(); sort(mp+1, mp+1+n); mp[0]=unique(mp+1, mp+1+n)-mp-1; for(int i=1;i<=n;i++) a[i]=lower_bound(mp+1, mp+1+mp[0], a[i])-mp; for(int i=1;i<n ;i++) ins(read(), read() ); block= sqrt(n); dfs(1); while(top) pos[st[top--]]=m; for(int i=1;i<=Q;i++){ u=read(), v=read(); if(pos[u]>pos[v]) swap(u, v); q[i]=(meow){u, v, i}; } sort(q+1, q+1+Q); modui(); for(int i=1;i<=Q;i++) printf("%d\n",ans[i]); }
相关文章推荐
- SPOJ COT2 Count on a tree II [树上莫队]
- SPOJ COT2 Count on a treeII 树上莫队
- SPOJ COT2 Count on a tree II(树上莫队)
- SPOJ.COT2 Count on a tree II(树上莫队)
- [spoj COT2- Count on a tree II] 树上莫队
- SPOJ-COT2 Count on a tree II(树上莫队)
- spoj_cot2 Count on a tree II(树上莫队+离散化)
- 【SPOJ】Count On A Tree II(树上莫队)
- SPOJ - COT2 : Count on a tree II (树上莫队)
- 【SPOJ COT2】Count on a tree II,树上莫队
- spoj_cot2 Count on a tree II(树上莫队+离散化)
- SPOJ10707 COT2 - Count on a tree II 【树上莫队】
- SPOJ 10707 Count on a Tree II 树上莫队
- [SPOJ COT2]-Count on a tree II-树上莫队
- SPOJ--Count on a tree II(树上莫队)
- SPOJ COT2 Count on a tree II 树上莫队算法
- 【SPOJ10707】Count on a tree II-树上莫队算法
- SPOJ Count on a tree II(树上莫队)
- SPOJ COT2 Count on a tree II(路径树上莫队)
- [树上莫队] SPOJ COT2 Count on a tree II