题目链接:https://cn.vjudge.net/problem/CodeForces-12D
题目大意:给你一个人的三个信息,如果存在一个人比当前人的这三个信息都大,那么这个人就会退出,问你最终有多少人退出。
具体思路:首先按照x的大小排序,大的在前面,然后对y进行离散化,其次就该使用线段树了,将y表示成区间,每一次更新的是y当前的到最大节点,然后线段树中储存的是z值,这样的话,每一次查询,在保证x变大的同时,通过对当前y+1-》siz的区间的z值的最大值,就能判断了。
AC代码:
#include<iostream>
#include<stack>
#include<stdio.h>
#include<map>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
# define lson l,m,rt<<
# define rson m+,r,rt<<|
# define ll long long
const int maxn = 1e5+;
ll sto1[maxn],sto2[maxn];
ll sto3[maxn];
ll cal(ll t1,ll t2)
{
ll tmp=;
while(t2)
{
tmp+=(t2/t1);
t2/=t1;
}
return tmp;
}
int main()
{
ll n,m,tmp;
scanf("%lld %lld",&n,&m);
tmp=m;
int num=;
for(ll i=; i*i<=m; i++)
{
int res=;
if(tmp%i==)
{
sto1[++num]=i;
while(tmp%i==)
{
tmp/=i;
res++;
}
sto2[num]=res;
}
}
if(tmp!=)sto1[++num]=tmp,sto2[num]=;
for(int i=; i<=num; i++)
{
sto3[i]=cal(sto1[i],n);
// cout<<sto1[i]<<" "<<sto2[i]<<" "<<sto3[i]<<endl;
}
ll minn=9e18+;
for(int i=; i<=num; i++)
{
minn=min(minn,sto3[i]/sto2[i]);
}
printf("%lld\n",minn);
return ;
}