LA-4382(威尔逊定理)

题意:

输入正整数n(1<=n<=1e6)计算f(k)=[((3k+6)!+1)/(3k+7)-floor((3k+6)!/(3k+7))]的和  (1<=k<=n);

思路:

当3k+7是合数的时候,那么3k+7肯定可以表示乘两个数的积,这两个数都比3k+7小,那么(3k+7)|(3*k+6)!这点除非3k+7==4时不成立,不过3k+7>4,所以floor[(3k+6)!/(3k+7)]==(3k+6)!/(3k+7),所以f(k)=0;

当3k+7是素数的时候(3k+6)!%(3k+7)==(3k+6)==-1;这是威尔逊定理得到的;(p-1)=1(modp);(p为素数);f(k)=1;

所以再素数筛筛一下就好了;

AC代码:

#include 
/*#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
*/
using namespace std;
#define Riep(n) for(int i=1;i<=n;i++)
#define Riop(n) for(int i=0;i void read(T&num) {
    char CH; bool F=false;
    for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
    for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
    F && (num=-num);
}
int stk[70], tp;
template inline void print(T p) {
    if(!p) { puts("0"); return; }
    while(p) stk[++ tp] = p%10, p/=10;
    while(tp) putchar(stk[tp--] + '0');
    putchar('\n');
}

const LL mod=1e9+7;
const double PI=acos(-1.0);
const LL inf=1e14;
const int N=3e6+10;

int p[N],vis[N];

void Init()
{
    p[0]=0;
    for(int i=2;i


你可能感兴趣的:(UVA)