NOI Online #3 Improve group T3 excellent subsequence

Original title link

Concise title

Request from AAA selects subsetBBB makesBBNo two numbers in B are bitwise and equal to0 00 . BBper subsetThe value of B is the sum of all the numbers in the set plus oneϕ \phiϕ value. Find all subsetsBBThe sum of B 's value.

analysis

You can think because you have to know all the set BBB is not easy, so considerBB with thesame valueThe number of B. Letfi f_ifiIndicates that all values ​​are iii 's subsetBBThe number of B , we calculatefi f_ifiMultiply by phii + 1 phi_{i+1}phii+1It is the value and sum of this plan, and adding up each value and sum is the answer. Consider how to calculate this fff , we can putfff is divided into two parts, and then one part is directly usedfj f_jfj, The other part uses the set AAJust make up the number of A. Because the title isBBThe bitwise sum of all numbers in B is equal to0 00 , so there will not be two numbers where one of the two numbers is1 11 situation. So we are dismantlingiii can putiii is1 1The bit of 1 is divided into two halves for calculation. To facilitate processing, we putnumx num_xn u mxIt represents aj a_jajMedian is xxthe number of x ,sss meansiia number divided by i ,ttt is the remaining part, in order to ensure no double calculation, it is required thats>= t s>=ts>=t , according to the principle of multiplication, there is a state transition equationfi + = fs × numt f_i+=f_s\times num_tfi+=fs×n u mt. But this has a problem: the upper limit of the sum of these numbers is too large, and the memory can't fit! Don’t worry, because the number we choose will not be both 1 1In the case of 1 , so the selected sum is naturally less than2 ⌊ log ⁡ 2 (max ⁡ {ai}) + 1 ⌋ 2^{\lfloor\log_2(\max\{a_i\})+1\rfloor}2log2(max{ ai})+1,以 2 ⌊ log ⁡ 2 ( max ⁡ { a i } ) + 1 ⌋ 2^{\lfloor\log_2(\max\{a_i\})+1\rfloor} 2log2(max{ ai} ) + 1 is the upper limit. But then there will be a situation:ai = 0 a_i=0ai=0 is missing! Actuallyai a_iaiEqual to 0 0It doesn’t matter whether it is 0 or not. According to the principle of multiplication, the answer should be multiplied by2 num 0 2^{num_0}2n u m0. As for the sieve method to find phi phip h i (that is, when sieving prime numbers,phi phip h i function) and find a subset of a set (to splitiii ), everyone should know it?

Code

#include<bits/stdc++.h>
using namespace std;
const int NN=300000,P=1e9+7;
int num[NN],phi[NN],f[NN];
bool vis[NN];
int main()
{
    
    
	int n,maxx=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
    
    
		int x;
		scanf("%d",&x);
		num[x]++;
		maxx=max(maxx,x);
	}
	int m=0;
	while((1<<m)<=maxx)
		m++;
	phi[1]=1;
	for(int i=2;i<=(1<<m);i++)
		if(!vis[i])
			for(int j=i;j<=(1<<m);j+=i)
			{
    
    
				vis[j]=true;
				if(!phi[j])
					phi[j]=j;
				phi[j]=phi[j]/i*(i-1);
			}
	f[0]=1;
	for(int i=1;i<=(1<<m);i++)
		for(int s=i;;s=(s-1)&i)
		{
    
    
			int t=i^s;
			if(s<t)
				break;
			f[i]=(f[i]+1ll*f[t]*num[s])%P;
		}
	int ans=0;
	for(int i=0;i<=(1<<m);i++)
		ans=(ans+1ll*f[i]*phi[i+1])%P;
	for(int i=1;i<=num[0];i++)
		ans=ans*2ll%P;
	printf("%d",ans);
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_44043668/article/details/109165796