Topic: Given a tree, each node has a color, many times asked the number of colors on a path, forcing online
Positive solution is a block array, forcing the online Mo team will be tle to die, want to ac this problem don't look
It's not hard to run a tree on the plain--but force online
So we can consider forcing the online Mo team algorithm
Divide the tree into O (N^1/3) blocks, each block size O (N^2/3)
Record the answers between each of the two pieces, the number of occurrences of each color, and what points are recorded in the answer
Each query first finds the answer to the end of the block at the end of each point, and then the violence is transferred with MO Team
Space complexity O (N^1/3) *o (N^1/3) *o (n) =o (N^5/3)
Preprocessing time complexity O (N^1/3) *o (N^1/3) *o (n) =o (N^5/3)
Single Query time complexity O (N^2/3)
And then... Be stuck constant ... Clearly this machine as long as less than 11 seconds can be all out of the solution ... BZ Slag evaluation machine how so slow ...
Read-in optimization ... Addressing optimization ... Short pressure memory ... inline assembly forced inline ... Change function to Macro ... Multiply LCA into Rmqlca ... Cubic method to modify the size of the block ... What else ...? BOOL changed to Bitset ... Random number selected root anti-card ... Also deliberately to cut the royal Federal Practice tree sub-block ... Add a note at the end to enhance your faith ...
From morning card to now ... Plus yesterday's version of the total hung seven articles ... A whole seven articles ....... .......
Send a map of local evaluation ... The spirit of the topic AC ...
I が career occupies, a piece of regret いなし ...
#include <bitset> #include <cstdio> #include <cstring> #include <iostream> #include < algorithm> #define M 40002#define B 95#define Change (X,f,v,ans) {if (V[x]) { if (!--f[a[x]])--ans; v[x]=0; } else {if (!f[a[x]]++) ++ans; V[x]=1; }} #define SWAP (x, y) {int t=x;x=y;y=t;} Using namespace Std;struct abcd{int to,next;} Table[m<<1];int Head[m],tot;int N,m,b,cnt,last_ans;int a[m],fa[m],dpt[m],log2[m<<1],min_dpt[m<< 1][20],into[m];int belong[m],root[m],stack[m],top;unsigned Short f[b* (B-1)/2*m+m];bitset<m> v[B][B];int Ans[B ][b],pos[b][b];__inline__ __attribute__ ((always_inline)) void Add (int x,int y) {table[++tot].to=y;table[tot].next= Head[x];head[x]=tot;} void DFS (int x) {static int t;intI,bottom=top;dpt[x]=dpt[fa[x]]+1;min_dpt[into[x]=++t][0]=x;for (I=head[x];i;i=table[i].next) if (table[i].to!=fa[ X]) {Fa[table[i].to]=x;dfs (table[i].to), if (top-bottom>=b) {while (Top!=bottom) belong[stack[top--]]=cnt;root[ Cnt++]=x;} Min_dpt[++t][0]=x;} Stack[++top]=x;} /*__inline__ __attribute__ ((always_inline)) void Change (int. x,unsigned short f[m],bitset<m> &v,int &ans) {if (v[x]) {if (!--f[a[x]])--ans;} Else{if (!f[a[x]]++) ++ans;} V[X]=!V[X];} */void pretreatment (int x,int y,unsigned short f[m],bitset<m> &v,int &ans) {if (Dpt[x]<dpt[y]) swap (x, y ); while (Dpt[x]>dpt[y]) {change (X,f,v,ans); x=fa[x];} while (x!=y) {change (X,f,v,ans); Change (Y,f,v,ans); x=fa[x];y=fa[y];}} __inline__ __attribute__ ((always_inline)) int Min (int x,int y) {return dpt[x]<dpt[y]?x:y;} __inline__ __attribute__ ((always_inline)) int LCA (int x,int y) {x=into[x];y=into[y];if (x>y) swap (x, y); int j=log2[ Y-x+1];return Min (min_dpt[x][j],min_dpt[y-(1<<j) +1][j]);} int Query (int x,int y) {static unsigned short f[m];static bitset<m> v;static int tim1[m],tim2[m],t;++t;if (belong[x]>belong[y]) swap (x, y); unsigned short *F =::f+pos[belong[x]][belong[y]];bitset<m> &v=::v[belong[x]][belong[y]];int ans=::ans[belong[x]][belong[ Y]];int l=root[belong[x]],r=root[belong[y]];unsigned Short Temp,a_t,lca=lca (l,x), for (int temp=x;temp!=lca;temp=fa[ Temp]) {a_t=a[temp];if (tim1[a_t]!=t) tim1[a_t]=t,f[a_t]=f[a_t];if (tim2[temp]!=t) tim2[temp]=t,v[temp]=v[temp]; Change (Temp,f,v,ans);} for (Temp=l;temp!=lca;temp=fa[temp]) {a_t=a[temp];if (tim1[a_t]!=t) tim1[a_t]=t,f[a_t]=f[a_t];if (Tim2[temp]!=T) TIM2[TEMP]=T,V[TEMP]=V[TEMP]; Change (Temp,f,v,ans);} Lca=lca (R,y); for (Temp=y;temp!=lca;temp=fa[temp]) {a_t=a[temp];if (tim1[a_t]!=t) tim1[a_t]=t,f[a_t]=f[a_t];if (tim2 [temp]!=t) tim2[temp]=t,v[temp]=v[temp]; Change (Temp,f,v,ans);} for (Temp=r;temp!=lca;temp=fa[temp]) {a_t=a[temp];if (tim1[a_t]!=t) tim1[a_t]=t,f[a_t]=f[a_t];if (Tim2[temp]!=T) TIM2[TEMP]=T,V[TEMP]=V[TEMP]; Change (Temp,f,v,ans);} Temp=lca (x, y); A_t=a[temp];if (tim1[a_t]!=t) tim1[a_t]=t,f[a_t]=f[a_t];if (tim2[temp]!=t) tim2[temp]=t,v[temp]=v[temp]; Change (Temp,f,v,ans); return ans;} namespace istream{const int l=1<<15; Char buffer[l],*s,*t; Char Get_char () {if (s==t) {t= (S=buffer) +fread (Buffer,1,l,stdin); if (s==t) return EOF; } return *s++; } int Get_int () {char C; int re=0; For (C=get_char ();c< ' 0 ' | | C> ' 9 '; C=get_char ()); while (c>= ' 0 ' &&c<= ' 9 ') re= (re<<1) + (re<<3) + (c ' 0 '), C=get_char (); return re; }}class ostream{private:static const int l=1<<15; Char Stack[20];int top; Char buffer[l],*s; Public:ostream () {s=buffer; } void Put_int (INT x,bool flag) {if (flag) stack[++top]= ' \ n '; if (!x) stack[++top]= ' 0 '; else while (x) stack[++top]=x%10+ ' 0 ', x/=10; while (top) {if (s==buffer+l-1) {//fwrite (buffer,1,s-b Uffer,stdout); printf ("%s", buffer); S=buffer; } *s++=stack[top--]; }} ~ostream () {//fwrite (buffer,1,s-buffer,stdout); *s=0;printf ("%s", buffer); }}os;int Main () {#ifndef online_judgefreopen ("2589.in", "R", stdin) freopen ("2589.out", "w", stdout); #endifstatic pair <int,int*> b[m];int i,j,x,y;cin>>n>>m;::b=420;for (i=1;i<=n;i++) B[i].first=istream::get_int ( ), B[i].second=&a[i];sort (b+1,b+n+1); for (i=1;i<=n;i++) {static int tot=0;if (i==1| | B[i].first!=b[i-1].first) ++tot;*b[i].second=tot;} for (i=1;i<n;i++) {x=istream::get_int (); Y=istream::get_int (); ADD (x, y); ADD (y,x);} int R=6854654%n+1;dfs (R), if (!cnt) root[cnt++]=r;while (top) belong[stack[top--]]=cnt-1;log2[0]=-1;for (i=1;i<= N-1<< 1;i++) Log2[i]=log2[i>>1]+1;for (j=1;j<=log2[n-1<<1];j++) for (i=1;i+ (1<<J) -1<=n-1< <1;i++) Min_dpt[i][j]=min (min_dpt[i][j-1],min_dpt[i+ (1<<j-1)][j-1]); for (i=0;i<cnt;i++) for (j=i+1;j <cnt;j++) {static int t;pos[i][j]= (++T) *m;if (j==i+1) pretreatment (Root[i],root[j],f+pos[i][j],v[i][j],ans[i][j] ); else{memcpy (f+pos[i][j],f+pos[i][j-1],sizeof (unsigned short) *m); v[i][j]=v[i][j-1];ans[i][j]=ans[i][j-1]; Pretreatment (Root[j],root[j-1],f+pos[i][j],v[i][j],ans[i][j]);}} for (i=1;i<=m;i++) {x=istream::get_int () ^last_ans;y=istream::get_int (); Os.put_int (Last_ans=query (x, y), i<m) ;} /*os. Put_int (2147483647,true); sort (root,root+cnt); for (i=0;i<cnt;i++) OS. Put_int (root[i],true); */return 0;} /*アナタガ Wang ムノナラバ dog ノヤウニ 淫従の螺旋 shun ni new ni Okinawa ni lock ni bind ラレテアゲマセウ*/
Card constant Dog I'll screw your mother.
One day I'll use the MO team algorithm to pass the problem.
Bzoj 2589 spoj 10707 Count on a tree II force online MO Team Algorithm (TLE)