可持久化可并堆QWQ
传送门:
http://blog.csdn.net/liuguangzhe1999/article/details/51132255
听说这位大神AK了省选%%%
主要思想就是讲一个可并堆当做一个状态然后转递给后面的状态
#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#include<cstdlib>
using namespace std;
#define ll long long
char c;
inline int ra(){return rand();}
inline void read(int &a)
{a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}
inline void read(ll &a)
{a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}
struct Sp{int u,v;ll key;inline friend bool operator <(Sp a,Sp b){return a.key<b.key;}};
priority_queue<Sp>Q;
struct Node
{
Node *lc,*rc;
ll D,flag;
Node(){D=1,flag=1,lc=NULL,rc=NULL;};
}*Cache;
int Cachetot=10000001;
const
int MaxCache=1000000;
ll con;
inline Node *New(){
con++;if(Cachetot>MaxCache)Cache=new Node[MaxCache],Cachetot=0;Cache[Cachetot].flag=1;return Cache+Cachetot++;}
ll n;
int t,m;
inline void Pushdown(Node *&A)
{
t++;
Node *AA;
if(A->lc)
{
AA=A->lc;
A->lc=New();*A->lc=*AA;
A->lc->flag*=A->flag;
A->lc->D*=A->flag;
}
if(A->rc)
{
AA=A->rc;
A->rc=New();*A->rc=*AA;
A->rc->flag*=A->flag;
A->rc->D*=A->flag;
}
A->flag=1;
}
inline Node*Addflag(Node *A,ll flag)
{
Node *N=New();
*N=*A;
N->flag*=flag;
N->D*=flag;
return N;
}
inline ll Top(Node *L)
{return L==NULL?0:L->D;}
Node*Merge(Node *L,Node *R)
{
Node *A=New();
if(L==NULL)return *A=*R,A;
if(R==NULL)return *A=*L,A;
if(L->flag!=1)Pushdown(L);
if(R->flag!=1)Pushdown(R);
if(ra()&1)
{
if(L->D<R->D)*A=*R,A->lc=Merge(R->lc,L),A->rc=R->rc;
else *A=*L,A->lc=Merge(L->lc,R),A->rc=L->rc;
}
else
{
if(L->D<R->D)*A=*R,A->rc=Merge(R->rc,L),A->lc=R->lc;
else *A=*L,A->rc=Merge(L->rc,R),A->lc=L->lc;
}
return A;
}
inline ll Pop(Node *&A)
{
if(A==NULL)return 0;
int res;
if(A->flag!=1)Pushdown(A);
if(A->lc==NULL)return res=A->D,A=A->rc,res;
if(A->rc==NULL)return res=A->D,A=A->lc,res;
return res=A->D,A=Merge(A->lc,A->rc),res;
}
bool Check[2346];
int tot,Prime[2346];
Node *f[236][2346];
Node *g[236][2346];
ll V[236][23996];
inline void Pre()
{
int i,j,t;
ll k;
read(n),read(m);
for(i=2;i<128;i++)
{
if(!Check[i])
{
Prime[++tot]=i;
ll last=1;
for(j=1,k=i;k>=last&&k<=n;j++,last=k,k*=i)V[tot][j]=k;
}
for(j=1;j<=tot&&(k=i*Prime[j])<128;j++)
{
Check[k]=true;
if(i%Prime[j]==0)break;
}
}
g[0][0]=New();
for(i=1;i<=tot;i++)
g[i][0]=g[0][0];
for(i=1;i<=tot;i++)
for(j=1;V[i][j];j++)
{
if(i==17&&j==10)
i++,i--;
for(k=1;k<=j;k++)
if(g[i-1][j-k])f[i][j]=Merge(f[i][j],Addflag(g[i-1][j-k],V[i][k]));
Q.push((Sp){i,j,f[i][j]->D});
g[i][j]=Merge(g[i-1][j],f[i][j]);
}
}
Sp Kyy[100001];
int ttt;
inline void Ans()
{
Sp K;
for(int i=1;i<m;i++)
{
K=Q.top();
Q.pop();
Pop(f[K.u][K.v]);
Q.push((Sp){K.u,K.v,Top(f[K.u][K.v])});
}
K=Q.top();
cout<<K.key<<endl;
}
int main()
{
Pre();
Ans();
return 0;
}