最近考试题一直改不完,不过还是想写一篇博客
[NOIP模拟测试26(A)T2]
下午2:00 下定决心改过T2(跟他们说复习一下树剖板子)
下午3:00终于看懂原理,开始码
下午3:01突然发现考试代码改一改可以成标准的暴力
下午3:30发现暴力可以得到87分,于是动了邪念。。。。(决定用分块艹过)
期间请教死缠了skyh和remarkable 大佬,几次产生放弃念头(唉,我还是打正解吧)
8:30尝试更改块的大小,终于AC。
学到的东西:
1.分块万能。
自己YY的树上分块:
1 //预处理 2 void dfs(const int x,const int kp){ 3 dfn[x]=++tot; 4 if(t&&d[x]%t==0)ed[x]=1; 5 tp[x]=kp; 6 for(int i=head[x],y;i;i=nxt[i]) 7 { 8 y=to[i]; 9 d[y]=d[x]+1; 10 if(ed[x])tp[y]=y,er[y].set(a[y]),dfs(y,y); 11 else tp[y]=tp[x],er[y]=er[x],er[y].set(a[y]),dfs(y,kp); 12 } 13 } 14 //询问 15 for(register int i=1;i<=c;++i) 16 { 17 register int now=p[i]; 18 while(fa[tp[now]]&&d[fa[tp[now]]]>=d[lc]) 19 { 20 s[i]|=er[now]; 21 now=fa[tp[now]]; 22 } 23 while(1) 24 { 25 s[i].set(a[now]); 26 if(now==lc)break; 27 now=fa[now]; 28 } 29 }
2.手打bitset
1 struct bitset{ 2 unsigned long long bit[16]; 3 inline void reset(){ 4 for(register int i=0;i^16;i+=4) bit[i]=bit[i|1]=bit[i|2]=bit[i|3]=0; 5 } 6 inline friend void operator |=(bitset &a,const bitset &b){ 7 for(register int i=0;i^16;i+=4) a.bit[i]|=b.bit[i],a.bit[i|1]|=b.bit[i|1],a.bit[i|2]|=b.bit[i|2],a.bit[i|3]|=b.bit[i|3]; 8 } 9 inline friend bitset operator |(const bitset &a,const bitset &b){ 10 bitset ans; 11 for(register int i=0;i^16;i+=4) ans.bit[i]=a.bit[i]|b.bit[i],ans.bit[i|1]=a.bit[i|1]|b.bit[i|1],ans.bit[i|2]=a.bit[i|2]|b.bit[i|2],ans.bit[i|3]=a.bit[i|3]|b.bit[i|3]; 12 return ans; 13 } 14 inline void set(const int x){ 15 bit[x/64]|=(unsigned long long)1<<(x&63); 16 } 17 inline int count(){ 18 register int cnt=0; 19 for(int i=0;i<16;++i) 20 cnt+=ct[bit[i]&65535]+ct[(bit[i]>>16)&65535]+ct[(bit[i]>>32)&65535]+ct[(bit[i]>>48)&65535]; 21 return cnt; 22 } 23 };
3.适时调整块的大小
4.多想一些东西。
AC代码:
1 #include<cstring> 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 using namespace std; 6 const int L=1<<20|1; 7 char buf[L],*S,*T; 8 #define getchar() ((S==T&&(T=(S=buf)+fread(buf,1,L,stdin),S==T))?EOF:*S++) 9 int dfn[300005],f[300005][20]; 10 int t; 11 int head[300005],to[300005],nxt[300005],cnt,p[6],a[300005],nk[6],c,ans,n,m,q,tot,d[300005],tcnt[105],yk[105],maxd,tp[300005],ct[65600],fa[300005]; 12 char ed[300005]; 13 struct bitset{ 14 #define lowbit(x) (x&-x) 15 unsigned long long bit[16]; 16 inline void reset(){ 17 for(register int i=0;i^16;i+=4) bit[i]=bit[i|1]=bit[i|2]=bit[i|3]=0; 18 } 19 inline friend void operator |=(bitset &a,const bitset &b){ 20 for(register int i=0;i^16;i+=4) a.bit[i]|=b.bit[i],a.bit[i|1]|=b.bit[i|1],a.bit[i|2]|=b.bit[i|2],a.bit[i|3]|=b.bit[i|3]; 21 } 22 inline friend bitset operator |(const bitset &a,const bitset &b){ 23 bitset ans; 24 for(register int i=0;i^16;i+=4) 25 ans.bit[i]=a.bit[i]|b.bit[i],ans.bit[i|1]=a.bit[i|1]|b.bit[i|1],ans.bit[i|2]=a.bit[i|2]|b.bit[i|2],ans.bit[i|3]=a.bit[i|3]|b.bit[i|3]; 26 return ans; 27 } 28 inline void set(const int x){ 29 bit[x/64]|=(unsigned long long)1<<(x&63); 30 } 31 inline int count(){ 32 register int cnt=0; 33 for(int i=0;i<16;++i) 34 cnt+=ct[bit[i]&65535]+ct[(bit[i]>>16)&65535]+ct[(bit[i]>>32)&65535]+ct[(bit[i]>>48)&65535]; 35 return cnt; 36 } 37 }s[6],ak[32],er[300005]; 38 inline void Add(const int u,const int v) 39 { 40 to[++cnt]=v; 41 nxt[cnt]=head[u]; 42 head[u]=cnt; 43 return ; 44 } 45 void dfs(const int x,const int kp){ 46 dfn[x]=++tot; 47 if(t&&d[x]%t==0)ed[x]=1; 48 tp[x]=kp; 49 for(int i=head[x],y;i;i=nxt[i]) 50 { 51 y=to[i]; 52 d[y]=d[x]+1; 53 if(ed[x])tp[y]=y,er[y].set(a[y]),dfs(y,y); 54 else tp[y]=tp[x],er[y]=er[x],er[y].set(a[y]),dfs(y,kp); 55 } 56 } 57 int Q[300005],l,r; 58 inline int lca(int a,int b) 59 { 60 if(d[a]>d[b])a^=b^=a^=b; 61 for(int t=18;t>=0;t--) 62 if(f[b][t]&&d[a]<=d[f[b][t]])b=f[b][t]; 63 if(a==b)return a; 64 for(int t=18;t>=0;t--) 65 if(f[a][t]&&f[a][t]!=f[b][t])a=f[a][t],b=f[b][t]; 66 return f[a][0]; 67 } 68 inline int read(register int x=0,register char ch=getchar()){ 69 while(ch<48||ch>57) ch=getchar(); 70 while(ch>=48&&ch<=57) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); 71 return x; 72 } 73 char cp[10],top; 74 inline void write(int x){ 75 do{ 76 cp[top++]=x%10,x/=10; 77 }while(x); 78 do{ 79 putchar(cp[--top]+48); 80 }while(top); 81 putchar(10); 82 } 83 int main() 84 { 85 n=read(); m=read(); q=read(); 86 for(int i=1;i<=65535;++i) ct[i]=ct[(i&-i)^i]+1; 87 yk[1]=1,yk[2]=2,yk[4]=3,yk[8]=4,yk[16]=5; 88 for(int i=1;i<=31;++i) 89 for(int j=1;j<=5;++j) 90 if(i&(1<<(j-1)))tcnt[i]++; 91 for(int i=2;i<=n;Add(fa[i],i),++i) fa[i]=read(); 92 for(int i=1;i<=n;++i) a[i]=read(); 93 t=pow(n,0.555); 94 dfs(1,1); 95 for(int j=1;j<=n;++j){ 96 f[j][0]=fa[j]; 97 for(int i=0;i<18;++i) 98 f[j][i+1]=f[f[j][i]][i]; 99 } 100 while(q--) 101 { 102 c=read(); ans=0x7f7f7f7f; 103 for(register int i=1;i<=c;++i) p[i]=read(); 104 register int now=-1,pa,pb; 105 for(register int i=1;i<=c;++i) 106 for(register int j=i+1;j<=c;++j) 107 if(abs(dfn[p[i]]-dfn[p[j]])>now)pa=p[i],pb=p[j],now=abs(dfn[p[i]]-dfn[p[j]]); 108 register int lc=lca(pa,pb); 109 for(register int i=1;i<=c;++i) 110 { 111 register int now=p[i]; 112 while(fa[tp[now]]&&d[fa[tp[now]]]>=d[lc]) 113 { 114 s[i]|=er[now]; 115 now=fa[tp[now]]; 116 } 117 while(1) 118 { 119 s[i].set(a[now]); 120 if(now==lc)break; 121 now=fa[now]; 122 } 123 } 124 for(register int i=1;i<1<<c;++i) 125 { 126 ak[i]=ak[i^(i&-i)]|s[yk[i&-i]]; 127 ans=min(ans,(int)ak[i].count()/tcnt[i]); 128 } 129 for(register int i=1;i<=c;++i)s[i].reset(); 130 write(ans*c); 131 } 132 return 0; 133 }