CF 2013-2014CTS01E04(Killer Challenge-将质因数存在 进行Bitmask)




首先,把P进行质因数分解,每一个不用的质因数压成1位

f[i][j]表示1前i位用j“拥有”的质因数表示。

然后都懂得。。。




#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#include<cmath>
#include<cctype>
#include<cassert>
#include<climits>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define RepD(i,n) for(int i=n;i>=0;i--)
#define MEM(a) memset(a,0,sizeof(a))
#define MEMI(a) memset(a,127,sizeof(a))
#define MEMi(a) memset(a,128,sizeof(a))
#define INF (2139062143)
#define F (1000000009)
#define MAXN (1000+10)
#define MAXM (1000+10)
typedef long long ll;
int T,n,P,p[MAXN],m,a[MAXN],s[MAXN],w[MAXN][MAXN],bin[MAXN],f[MAXN][MAXM];
int main()
{
   freopen("CF-2013CTS01E04-challenge.in","r",stdin);
   cin>>T;
   bin[1]=1;Fork(i,2,30) bin[i]=bin[i-1]<<1;
// For(i,30) cout<<bin[i]<<' ';    
   while(T--)
   {
      cin>>n>>P;m=0;
      int P2=P;
      Fork(i,2,sqrt(P)) 
         if (P%i==0)
         {
            P/=i;
            p[++m]=i;
         }
      if (P) p[++m]=P;
      P=P2;
      s[0]=0; For(i,n) cin>>a[i],s[i]=s[i-1]+a[i];
      //For(i,m) cout<<p[i]<<' ';cout<<endl;
//    memset(w,0,sizeof(w));
      For(i,n)
         Fork(j,i,n)
         {
            w[i][j]=0;
            int t=s[j]-s[i-1];
            For(k,m)
               if (t%p[k]==0) w[i][j]|=bin[k];
         }
      MEMI(f);  
//    cout<<w[2][2]<<endl;
      For(i,n)
         Rep(j,bin[m+1])
         {
            if ((w[1][i]&j)==j) f[i][j]=min(f[i][j],0);
            Fork(k,i+1,n)
            {
               f[k][w[i+1][k]|j]=min(f[k][w[i+1][k]|j],f[i][j]+1);
            }
         }
      int ans=1,mincut=0;
      Rep(i,bin[m+1])
      {
         int t=1;
         For(k,m) if (bin[k]&i) t*=p[k];
         if (t>ans&&f[n][i]^INF)
         {
            ans=t;mincut=f[n][i];
         }
      }
      cout<<ans<<' '<<mincut<<endl;
      
      
   }   
   while(1);
   return 0;
}




原文地址:https://www.cnblogs.com/james1207/p/3366111.html