[链分治] LOJ #511. 「LibreOJ NOI Round #1」验题
来源:互联网 发布:数据预测模型有哪些 编辑:程序博客网 时间:2024/05/16 19:46
直接按照字典序类似逐位确定
先从后往前诸位确定确定答案和当前的LCP
然后在从前往后逐位确定
然后就转化为一个 某些不能选 某些必须选 某些随意 的独立集计数
链分治
#include<cstdio>#include<cstdlib>#include<algorithm>#include<vector>#define pb push_backusing namespace std;typedef long double ld;typedef long long ll;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline void read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}inline void read(ll &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}inline void write(int x){ if (x>=10) write(x/10); putchar('0'+x%10);}const int N=1000005;const int M=30000005;struct edge{ int u,v,next;}G[N<<1];int head[N],inum;inline void add(int u,int v,int p){ G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;}#define V G[p].vint depth[N],fat[N],size[N];inline void dfs(int u,int fa){ depth[u]=depth[fa]+1; fat[u]=fa; size[u]=1; for (int p=head[u];p;p=G[p].next) if (V!=fa) dfs(V,u),size[u]+=size[V];}int maxd[N],pre[N],clk,back[N],top[N],son[N];inline void find(int u,int fa,int z){ pre[u]=++clk; back[clk]=u; top[u]=z; maxd[z]=max(maxd[z],depth[u]); int maxv=0; son[u]=0; for (int p=head[u];p;p=G[p].next) if (V!=fa && size[V]>maxv) maxv=size[son[u]=V]; if (son[u]) find(son[u],u,z); for (int p=head[u];p;p=G[p].next) if (V!=fa && V!=son[u]) find(V,u,V);}ld K;int ncnt,rt1[N],rt2[N];int ls[M],rs[M],ps[M];ld T[M>>1][2][2],F0[M>>1],F1[M>>1];inline void upd2(int x){ F0[x]=min(F0[ls[x]]*F0[rs[x]],K); F1[x]=min(F1[ls[x]]*F1[rs[x]],K);}vector<int> ch; int pos2[N];inline void build2(int &x,int l,int r,int p=0){ x=++ncnt; ps[x]=p; if (l==r){ int u=ch[l-1]; pos2[u]=x; F0[x]=min(T[rt1[u]][0][1]+T[rt1[u]][1][0]+T[rt1[u]][0][0]+T[rt1[u]][1][1],K); F1[x]=min(T[rt1[u]][0][1]+T[rt1[u]][0][0],K); return; } int mid=(l+r)>>1; build2(ls[x],l,mid,x); build2(rs[x],mid+1,r,x); upd2(x);}inline void upd1(int x){ for (int i=0;i<2;i++) for (int j=0;j<2;j++) T[x][i][j]=min(K,T[ls[x]][i][0]*T[rs[x]][0][j]+T[ls[x]][i][0]*T[rs[x]][1][j]+T[ls[x]][i][1]*T[rs[x]][0][j]);}int _pre;int pos1[N];inline void build1(int &x,int l,int r,int p=0){ x=++ncnt; ps[x]=p; if (l==r){ int u=back[_pre+l-1]; pos1[u]=x; T[x][0][0]=F0[rt2[u]]; T[x][1][1]=F1[rt2[u]]; T[x][0][1]=T[x][1][0]=0; return; } int mid=(l+r)>>1; build1(ls[x],l,mid,x); build1(rs[x],mid+1,r,x); upd1(x);}int n;inline void Build(){ static int idx[N],c[N]; F0[0]=F1[0]=1; for (int i=1;i<=n;i++) c[depth[i]]++; for (int i=1;i<=n;i++) c[i]+=c[i-1]; for (int i=1;i<=n;i++) idx[c[depth[i]]--]=i; for (int i=n;i;i--){ int u=idx[i]; for (int p=head[u];p;p=G[p].next) if (V!=fat[u] && V!=son[u]) ch.pb(V); if (ch.size()) build2(rt2[u],1,ch.size()); ch.clear(); if (top[u]==u){ _pre=pre[u]; build1(rt1[u],1,maxd[u]-depth[u]+1); } }}int f[N];inline void modify(int u,int _f){ // f:0 mustn't 1 must 2 poss f[u]=_f; int t=pos1[u],v; T[t][0][0]=f[u]==1?0:F0[rt2[u]]; T[t][1][1]=f[u]==0?0:F1[rt2[u]]; while (t=ps[t]) upd1(t); while (v=fat[top[u]]){ u=top[u]; t=pos2[u]; F0[t]=min(T[rt1[u]][0][1]+T[rt1[u]][1][0]+T[rt1[u]][0][0]+T[rt1[u]][1][1],K); F1[t]=min(T[rt1[u]][0][1]+T[rt1[u]][0][0],K); while (t=ps[t]) upd2(t); t=pos1[v]; T[t][0][0]=f[v]==1?0:F0[rt2[v]]; T[t][1][1]=f[v]==0?0:F1[rt2[v]]; while (t=ps[t]) upd1(t); u=v; }}#define Tot min(T[rt1[1]][0][0]+T[rt1[1]][0][1]+T[rt1[1]][1][0]+T[rt1[1]][1][1],K)int I[N];int main(){ ll k; static int iu[N],iv[N]; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(k); K=k+5; for (int i=1;i<n;i++) read(iu[i]),iu[i]++; for (int i=1;i<n;i++) read(iv[i]),iv[i]++,add(iu[i],iv[i],++inum),add(iv[i],iu[i],++inum); read(*I); for (int i=1;i<=*I;i++) read(I[i]),I[i]++; sort(I+1,I+*I+1); dfs(1,0); find(1,0,1); Build(); for (int i=1;i<=n;i++) f[i]=2; for (int i=1;i<=*I;i++){ for (int j=(i==1?0:I[i-1])+1;j<I[i];j++) modify(j,0); modify(I[i],1); } int c=0; for (int i=*I;i;i--){ if (Tot-1<k) k-=Tot-1; else break; modify(I[i],0); c++; for (int j=I[i]+1;j<=(i==*I?n:I[i+1]);j++) modify(j,2); } *I-=c; if (Tot-1<k) return printf(""),0; for (int i=1;i<=n;i++){ if (f[i]!=2) continue; modify(i,1); if (Tot<k){ k-=Tot; modify(i,0); }else I[++*I]=i,k--; if (!k) break; } for (int i=1;i<=*I;i++) write(I[i]-1),putchar(' '); return 0;}
阅读全文
0 0
- [链分治] LOJ #511. 「LibreOJ NOI Round #1」验题
- [数论] LOJ #510. 「LibreOJ NOI Round #1」北校门外的回忆
- [反演] LOJ #509. 「LibreOJ NOI Round #1」动态几何问题
- [数论] LOJ #508. 「LibreOJ NOI Round #1」失控的未来交通工具
- #507. 「LibreOJ NOI Round #1」接竹竿 dp
- loj#526. 「LibreOJ β Round #4」子集
- [DP 倍增Floyd] LOJ#539.「LibreOJ NOIP Round #1」旅游路线
- 「LibreOJ NOI Round #1」接竹竿 (dp+前缀和优化)
- 【DP】LibreOJ NOI Round #1[A.接竹竿]题解
- [DP]LOJ NOI Round #1——接竹竿
- LibreOJ NOIP Round #1
- LibreOJ #505.「LibreOJ β Round」ZQC 的游戏 网络流
- LibreOJ #504. 「LibreOJ β Round」ZQC 的手办 线段树+堆
- [结论] LibreOJ #520. 「LibreOJ β Round #3」绯色 IOI(开端)
- [匹配+拓扑] LibreOJ #521. 「LibreOJ β Round #3」绯色 IOI(抵达)
- [数学杂题] LibreOJ #530「LibreOJ β Round #5」最小倍数
- [数学杂题] LibreOJ#532. 「LibreOJ β Round #5」随机数列
- 「LibreOJ β Round #2」DP 一般看规律
- 通知
- 评估算法的“时间复杂度”与“空间复杂度”
- HDU
- 【Android 数据业务解析】nwTypeChanged引发的原因
- 高端的bfc
- [链分治] LOJ #511. 「LibreOJ NOI Round #1」验题
- 【ulua入门】lua实现面向对象编程
- nyoj-114 某种序列
- failure during conversion to COFF: file invalid or corrupt
- python核心高级学习总结8------动态性、__slots__、生成器、迭代器、装饰、闭包
- URI和URL
- NYOJ 455 黑色帽子
- bzoj4829 [TJOI2017]dna(后缀数组)
- How to excute jquery by nodejs?