BZOJ4524: [Cqoi2016]伪光滑数

来源:互联网 发布:mac 加速器 编辑:程序博客网 时间:2024/05/01 17:28

可持久化可并堆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 longchar 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;}
0 0
原创粉丝点击