洛谷月赛 礼物
题解:
首先我们会发现题目限制等价于要同一个组中的数不能再2进制下呈包含关系
然后可以建一张邮箱无图,找最长链
我们考虑ai只有10^6
从大到小考虑,枚举删掉每一位的连边方法
复杂度20*10^6
这么做的正确性是显然的
因此从小到大插入每个数,贪心的放在前面这个正确性可以反证
代码:
#include <bits/stdc++.h> using namespace std; #define rint register int #define IL inline #define rep(i,h,t) for (rint i=h;i<=t;i++) #define dep(i,t,h) for (rint i=t;i>=h;i--) char ss[1<<24],*A=ss,*B=ss; IL char gc() { return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++; } template<class T>void read(T &x) { rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=c^48; while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f; } char sr[1<<24],z[20]; int Z,C=-1; template<class T>void wer(T x) { while (z[++Z]=x%10+48,x/=10); while (sr[++C]=z[Z],--Z); } const int N=2e6; int a[N],dis[N]; bool f[N]; int jl[22][N],cnt2[22]; int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); int n,m; read(n); read(m); rep(i,1,n) read(a[i]),f[a[i]]=1,dis[a[i]]=1; int t=(1<<20)-1; dep(i,t,0) if (dis[i]) { rep(j,1,20) { rint now=i^(1<<(j-1)); if (((i>>(j-1))&1)&&dis[i]+f[now]>dis[now]) dis[now]=dis[i]+f[now]; } } dep(i,t,0) if (!f[i]) dis[i]=0; int maxa=0; rep(i,0,t) if (dis[i]>maxa) maxa=dis[i]; wer(1); sr[++C]='\n'; wer(maxa); sr[++C]='\n'; rep(j,0,t) if (dis[j]) jl[dis[j]][++cnt2[dis[j]]]=j; /* rep(i,1,maxa) { int cnt=0; rep(j,0,t) if (dis[j]==i) cnt++; wer(cnt); sr[++C]=' '; rep(j,0,t) if (dis[j]==i) { wer(j); sr[++C]=' '; } sr[++C]='\n'; }*/ rep(i,1,maxa) { wer(cnt2[i]); sr[++C]=' '; rep(j,1,cnt2[i]) wer(jl[i][j]),sr[++C]=' '; sr[++C]='\n'; } fwrite(sr,1,C+1,stdout); return 0; }