题解 - 非单一点U367093
unconquerable · · 个人记录
题目
传送门
正解
单独讨论
不妨设
定义
则有
那么我们可以求出
那么我们回到原题。
由于非单一点的第二个条件,我们得知它在圆
不妨设
那么我们有:
例如,当
样例答案为
假设
显然
则有
显然
那么我们就能发现非单一点的数量
统计与
AC代码:
#include <iostream>
#include <cstring>
using namespace std;
const int N = (int)5e6;
int a[N];
inline void read(int &x) { // 返回类型必须为void,否则竞赛中Linux测评会报错,Windows没事
x = 0;
short flag = 1;
char c = getchar();
while(c < '0' || c > '9'){
// 此处如果只用if的话容易在数据不规范时出错,特别是cin和read混用
if(c == '-')flag = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = (x << 3) + (x << 1) + (c ^ 48); // 48这个数字恰好往后10个数都可以使用位运算,可以写成二进制证明;位运算能用当然更好
c = getchar();
}
x *= flag;
}
/*
inline int read()
{
int X = 0, w = 0; char ch = 0;
while (!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
return w ? -X : X;
}
*/
inline void write(int x)
{
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
void phi_table() //打表,求出1500000中所有的数的欧拉函数值
{
memset(a,0,sizeof(a));a[1]=1;
for(register int i=2;i<=N;++i)
if(!a[i])
{
for(register int j=i;j<=N;j+=i)
{
if(!a[j])a[j]=j;
a[j]=a[j]/i*(i-1);
}
}
}
int main(){
int T,n;
read(T);
phi_table();
while (T--) {
read(n);
write(n+1-a[n+1]);
putchar('\n');
}
return 0;
}