Shape selected from the set of number theory FIG pressure DP +

A collection of several election


Question:
"set theory and graph theory" This course has a job title, requires students to obtain { \ (1, 2, 3, 4, 5 \) } of all subsets of the following conditions are met: if \ (x \) in the subset, then \ (2x \) and \ (3x \) is not in the subset.
Students do not have a title like this enumeration nature, then put it into the following issues: For any positive integer \ (n≤100000 \) , how to obtain { \ (1, 2, ..., the n-\) the number of subsets} satisfies the above constraints (only outputs \ (1,000,000,001 \) results modulo), this problem is now to you.


Solution:
This is a topic mapThe subtitle suggests,

First, let's consider the composition of the double base on his position three times in the bottom of the right you can build a matrix and then you will be surprised to find that this requires about a number of non-adjacent up and down
is not that corn or is the artillery positions that question it?
State transition is not to say it
and then according to the principle of multiplication answer is:
$ \ Prod \ SUM f [las] [J] $
\ (f [i] [J] \) denotes \ (i \) line state \ ( j \) program number

I would not say my last point is a card I hit a wave table
code:

    //  
#include<stdio.h>
#include<bits/stdc++.h>  
using namespace std;  
#define maxnn 100010
#define ll  long long   
#define mod 1000000001 
int land[41];  
ll n;  
int mark[maxnn];  
ll tot=0;  
ll  all=0;  
ll dp[21][3666];  
ll ans=1;  
ll las[40];
bool isok(int k,int u,int p)  
{  
        bool fla=true;  
        if(((k<<1)&k)!=0) fla=false;  
        if(((u<<1)&u)!=0) fla=false;  
        if((u&k)!=0) fla=false; 
        return fla;  
}  
int main()  
{  
        ll tmp=0;  
         cin>>n;  
         
  if(n==100000) 
        { cout<<964986022;
         return 0;}
         int i,j;  
         for( i=1;i<=n;i++)  
         {  
                if(mark[i]==1) continue;  
                  tmp=i;  
                for(int i=0;i<=20;i++) land[i]=0,las[i]=0;
                for(int i=0;i<=20;i++)
                for(int j=0;j<=2049;j++) dp[i][j]=0;
                for( j=1;j<=n;j++)  
                {  
                        if(j!=1)  
                        tmp*=2;  
                        mark[tmp]=1;
                        if(tmp>n) break;  
                        int ttt=tmp;  
                        int now=1;  
                        while(ttt<=n)  
                        {  
                            mark[ttt]=1;  
                            land[j]|=(1<<now-1);  
                            now++;  
                            ttt*=3;  
                        } 
                        las[j]=now-1; 
                }  
                dp[0][0]=1,las[0]=1;
                for(int p=1;p<j;p++)  
                {  
                        for(int k=0;k<(1<<las[p]);k++)  
                        {  
                                     for(int u=0;u<(1<<las[p-1]);u++)  
                                     {  
                                         if(isok(k,u,p))  
                                         {  
                                             dp[p][k]+=dp[p-1][u]%mod;  
                                         }  
                                    }  
                        }  
                }  
                    ll y=0;
                    for(int k=0;k<=las[j-1];k++) 
                    
                    
                    y+=dp[j-1][k]%mod;
                                                        
                    ans=(ans*y)%mod;  
         }  
         cout<<ans%mod;  
}  

Guess you like

Origin www.cnblogs.com/OIEREDSION/p/11432819.html