SP15864 题解 & 迷思
NaCly_Fish · · 题解
题目链接
题目要求我们求出前
设
那就有一种比较靠谱的做法:先统计不超过
由此可以得到代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#define ll long long
#define N 100003
#define double long double
using namespace std;
int p;
inline int power(int a,int t){
int res = 1;
while(t){
if(t&1) res = (ll)res*a%p;
a = (ll)a*a%p;
t >>= 1;
}
return res;
}
struct node{
int v;
double lv;
inline node(int _v=0,double _lv=0):v(_v),lv(_lv){}
inline bool operator < (const node& rhs) const{
return lv < rhs.lv;
}
inline bool operator > (const node& rhs) const{
return lv > rhs.lv;
}
};
const double ln3 = log(3),ln2 = log(2);
ll n,cnt;
int L,d,ans,pw3 = 1,tmp;
priority_queue<node> ql;
priority_queue<node,vector<node>,greater<node> > qs;
vector<int> qL,qS;
int main(){
scanf("%lld%d",&n,&p);
double x = sqrt(2*ln2*ln3)*sqrt(n)-log(sqrt(6)),y;
L = x/ln3;
for(int j=0;j<=L;++j){
d = (x-j*ln3)/ln2;
tmp = (ll)power(2,d)*pw3%p;
y = d*ln2+j*ln3;
qs.push(node(tmp,y)),ql.push(node(2*tmp%p,y+ln2));
ans = (ans+2*tmp-pw3)%p,cnt += d+1;
if(ql.size()>9) ql.pop(),qs.pop();
pw3 = 3*pw3%p;
}
while(!ql.empty()) qL.push_back(ql.top().v),ql.pop();
while(!qs.empty()) qS.push_back(qs.top().v),qs.pop();
while(cnt<n){
ans = (ans+qL[qL.size()-1])%p;
cnt++,qL.pop_back();
}
while(cnt>n){
ans = (ans-qS[qS.size()-1])%p;
cnt--,qS.pop_back();
}
printf("%d",(ans+p)%p);
return 0;
}
update:这个估计值实际上很好算,就是先用估计 不超过