[cqoi2016]伪光滑数 解题报告
来源:互联网 发布:2017移动互联网数据 编辑:程序博客网 时间:2024/05/16 11:18
这题有点意思。。
考虑对于i个质因子,最大的质因子至多为j能生成的数。我们需要每次在其中取最大值,显然它可以用可持久化左偏树来维护。有
然后我们再用一个堆来维护所有可持久化左偏树的根的最小值。
= =膜拜一下大爷的做法(妈的为什么我做法总是这么傻逼!!):
左偏树的话时间复杂度当然是
但如果我们把左偏树改成暴力减小每个质因子然后全插进堆里的话。。时间复杂度是
#include<cstdio>#include<iostream>using namespace std;#include<cstring>#include<cmath>#include<algorithm>typedef long long LL;const LL N=1e18+5;const int K=8e5+5;const int A=128;const int P=35;const int Log=60;int prime[P];bool p[A+5];const int Left=1e6;struct LS{ int ls,rs; int dis; LL flag; LL data;}leftist[Left];int ltot=2;int root[Log+5][P];void out(int node){ printf("leftist[%d]={ls=%d,rs=%d,dis=%d,flag=%I64d,data=%I64d}\n",node,leftist[node].ls,leftist[node].rs,leftist[node].dis,leftist[node].flag,leftist[node].data);}void paint(int &node,LL flag){ if(node){ leftist[ltot]=leftist[node]; node=ltot++; leftist[node].flag*=flag; leftist[node].data*=flag; }}void pushdown(int node){ if(leftist[node].flag!=1){ paint(leftist[node].ls,leftist[node].flag),paint(leftist[node].rs,leftist[node].flag); leftist[node].flag=1; }}void merge(int &node,int u,int v){ //printf("Merge(%d,%d)\n",u,v); if(!u&&!v){ node=0; return; } if(!u){ node=v; return; } if(!v){ node=u; return; } node=ltot++; if(leftist[u].data<leftist[v].data)swap(u,v); leftist[node]=leftist[u]; pushdown(node); merge(leftist[node].rs,leftist[node].rs,v); if(leftist[leftist[node].rs].dis>leftist[leftist[node].ls].dis)swap(leftist[node].ls,leftist[node].rs); leftist[node].dis=leftist[leftist[node].rs].dis+1;}int heap[P*Log+K],htot=1;void out(){ for(int i=1;i<htot;++i)printf("%d ",heap[i]); puts("");}bool less_heap(int a,int b){ return leftist[heap[a]].data<leftist[heap[b]].data;}void down(int node){ for(int next=node<<1;next<htot;node=next,next<<=1){ if(next+1<htot&&less_heap(next,next+1))++next; if(less_heap(next,node))return; swap(heap[node],heap[next]); }}void up(int node){ for(int next=node>>1;next&&less_heap(next,node);node=next,next>>=1)swap(heap[node],heap[next]);}void add(int node){ if(node){ heap[htot]=node; up(htot++); }}int main(){ freopen("bzoj_4524.in","r",stdin); freopen("bzoj_4524.out","w",stdout); for(int i=2;i<A;++i){ if(!p[i])prime[++prime[0]]=i; for(int j=1;j<=prime[0]&&i*prime[j]<A;++j){ p[i*prime[j]]=1; if(i%prime[j]==0)break; } } LL n,tmp; int k; cin>>n>>k; leftist[1]=(LS){0,0,1,1,1}; for(int j=0;j<=prime[0];++j)root[0][j]=1; int u,v; for(int j=1,i;j<=prime[0];++j){ tmp=n; for(i=1;tmp>=prime[j];++i,tmp/=prime[j]){ u=root[i-1][j]; paint(u,prime[j]); v=root[i][j-1]; //cout<<"("<<i<<','<<j-1<<")="<<v<<endl; merge(root[i][j],u,v); //printf("root(%d,%d)=",i,j); //out(root[i][j]); } for(;i<=Log;++i)root[i][j]=root[i][j-1]; } for(int i=1;i<=Log;++i) if(root[i][prime[0]]){ //cout<<"Get("<<i<<","<<prime[0]<<")\n"; heap[htot++]=root[i][prime[0]]; } for(int i=htot;--i;)down(i); //out(); while(--k){ pushdown(heap[1]); if(leftist[heap[1]].ls)add(leftist[heap[1]].ls); if(leftist[heap[1]].rs)add(leftist[heap[1]].rs); heap[1]=heap[--htot]; down(1); //out(); if(htot==1){ puts("No answer"); return 0; } } cout<<leftist[heap[1]].data<<endl;}
总结:
①一个数的质因子个数是很少的!
0 0
- [cqoi2016]伪光滑数 解题报告
- CQOI2016 伪光滑数
- BZOJ4524: [Cqoi2016]伪光滑数
- [bzoj4524][CQOI2016]伪光滑数
- bzoj4524【CQOI2016】伪光滑数
- 4524: [Cqoi2016]伪光滑数
- 4524: [Cqoi2016]伪光滑数
- bzoj 4524 [Cqoi2016]伪光滑数
- 【bzoj4524】【CQOI2016】【伪光滑数】【堆+贪心】
- bzoj 4524: [Cqoi2016]伪光滑数
- BZOJ 4524: [Cqoi2016]伪光滑数
- CQOI2016 伪光滑数 可并堆+搜索
- bzoj 4524: [Cqoi2016]伪光滑数 优先队列
- [堆 思路题] BZOJ 4524 [Cqoi2016]伪光滑数
- BZOJ4524 [CQOI2016]伪光滑数 可持久化可并堆+DP
- CQOI2016题目&CQOI2016题解&不同的最小割&K远点对&手机号码&密匙破解&路由表&伪光滑数
- 【BZOJ 4524】【CQOI 2016】伪光滑数
- BZOJ 4524 CQOI 2016 伪光滑数 暴力
- 那些年,在MySQL上遇到的坑
- 鸟哥私房菜linux基础学习笔记 1
- UIscrollView 设置后 上面出现白条解决方法。
- 4/18
- 通过url调用边度地图的地理和反地理编码
- [cqoi2016]伪光滑数 解题报告
- 显示文件的某几行 某一行
- objectiveC【语法】修饰符 static extern const
- java 里面的string 和byte[] 怎么互转?
- 191. Number of 1 Bits
- Java—JDK的下载与安装
- UI实现之下拉刷新:SwipeRefreshLayout PullToRefres
- 数据结构之排序查找
- iOS - 社交分享- weibo分享