[JZOJ5352]【NOIP2017提高A组模拟9.7】计数题
2017-09-08 22:53
549 查看
Description
给定N个点,每个点有权值a[i]。定义一条无向边x,y,权值为a[x] xor a[y]
求这N个点构成的完全图的最小生成树
的边权和
以及它的方案数,方案数对1e9取模
N<=105,0≤a[i]≤230
Solution
既然是异或,我们可以按位考虑。用分治的思想
从高位到低位扫,对于当前位可以将处理的点分成两部分,分别是这一位上为0和为1的点
最优解一定是这两部分分别自己做最小生成树,然后这两部分之间连一条边。
因为其他的这一位上都是0,只有这条边这一位是1,根据2进制的性质这样一定最优
两部分可以递归处理,这两部分之间连边可以维护一个字典树处理,方案数直接乘进去。
特殊情况是当前处理的部分的点已经分治到2^0都不能分开,也就是当前部分所有点权值相同。
对边权和贡献一定是0,方案数就是完全图中生成树的数量
有公式
对于N个点完全图,生成树的数量为NN−2,当N>1
证明我还不会,留坑代填。。。
分析复杂度
分治每个二进制位只有一层,总共有log 层,每一层把所有点扫一遍,用字典树维护复杂度N log Maxa
总的复杂度是O(Nlog2Maxa)
Code
#include <cstdio> #include <cstdlib> #include <algorithm> #include <iostream> #include <cstring> #include <cmath> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fod(i,a,b) for(int i=a;i>=b;i--) #define N 100005 #define LL long long #define mo 1000000007 using namespace std; int n,a ,n1,vl; LL vs,ans; struct node { int a[2]; LL s; }tr[30*N]; LL ksm(LL k,LL n) { if(n<1) return 1; LL s=ksm(k,n/2); return (n%2)?s*s%mo*k%mo:s*s%mo; } void dfs(LL v,int l,int r) { if(l>=r) return; if(v==0) { (vs*=ksm(r-l+1,r-l-1))%=mo; return; } int mid=r+1; LL mi=2147483647,ms=0; fo(i,l,r) if(a[i]&v) { mid=i; break; } dfs(v/2,l,mid-1),dfs(v/2,mid,r); if(mid==l||mid==r+1) return; n1=1,tr[1].a[0]=tr[1].a[1]=tr[1].s=0; fo(i,l,mid-1) { LL vt=vl,k=1; while(vt) { LL p=((vt&a[i])>0); if(!tr[k].a[p]) tr[k].a[p]=++n1,tr[n1].a[0]=tr[n1].a[1]=tr[n1].s=0; k=tr[k].a[p],vt>>=1,tr[k].s++; } } fo(i,mid,r) { LL vt=vl,k=1,sq=0; while(vt) { LL p=((vt&a[i])>0); if(!tr[k].a[p]) sq+=vt,k=tr[k].a[1-p]; else k=tr[k].a[p]; vt>>=1; } if(sq==mi) (ms+=tr[k].s)%=mo; if(sq<mi) ms=tr[k].s,mi=sq; } ans+=mi,(vs*=ms)%=mo; } int main() { freopen("jst.in","r",stdin); freopen("jst.out","w",stdout); cin>>n; vl=0; fo(i,1,n) scanf("%d",&a[i]),vl=max(vl,a[i]); vl=1<<(int)log2(vl); ans=0,vs=1; sort(a+1,a+n+1); dfs(vl,1,n); printf("%lld\n%lld",ans,vs); }
相关文章推荐
- 【jzoj5350】【NOIP2017提高A组模拟9.7】【陶陶摘苹果】【动态规划】
- JZOJ5350. 【NOIP2017提高A组模拟9.7】陶陶摘苹果
- JZOJ 4630 计数【NOIP2016提高A组模拟7.15】
- jzoj5385. 【NOIP2017提高A组模拟9.23】Carry
- JZOJ 5392. 【NOIP2017提高A组模拟10.5】Lucky Transformation
- JZOJ 5395. 【NOIP2017提高A组模拟10.6】Count
- JZOJ 5401. 【NOIP2017提高A组模拟10.8】Star Way To Heaven
- JZOJ 5401. 【NOIP2017提高A组模拟10.8】Star Way To Heaven
- 【jzoj5360】【NOIP2017提高A组模拟9.12】【Shorten Diameter】
- jzoj5249 【NOIP2017提高A组模拟8.10】文本编辑器 (序列修改类问题,数据结构)
- JZOJ 5406. 【NOIP2017提高A组模拟10.10】Tree
- JZOJ 5182. 【NOIP2017提高组模拟6.29】码灵鼠
- {题解}[jzoj4924]【NOIP2017提高组模拟12.17】向再见说再见
- JZOJ5379. 【NOIP2017提高A组模拟9.21】Victor爱数字
- jzoj5402 【NOIP2017提高A组模拟10.8】God Knows
- 【JZOJ5287】【NOIP2017提高组模拟】最短路
- 【JZOJ5330】【NOIP2017提高A组模拟8.22】密码【51nod1569】二项式系数的个数
- JZOJ 5397. 【NOIP2017提高A组模拟10.6】Biology
- 【JZOJ 5400】【NOIP2017提高A组模拟10.7】Repulsed
- JZOJ5398. 【NOIP2017提高A组模拟10.7】Adore