原题链接

https://www.nowcoder.com/acm/contest/135#question

A-无关

就是先找出有关的,然后用总的减去有关的,剩下的就是无关的
比如要找在 N 内与 2 , 3 , 5 有关的数有多少个,
答案就是 a n s = ( N 2 + N 3 + N 5 ) ( N 2 3 + N 2 5 + N 3 5 ) + ( N 2 3 5 )
就是说奇数个加,偶数个减~
d f s 容斥
but~~~只能过 % 30 的数据。。。原因是爆 l o n g l o n g 了,用对数判断一下就 O j b k

C-水题

水题。。。哪里水了。。。。
这到题我还顺便学了一哈 n 皇后的状压那种
然后就是求 n 的阶乘在 m 进制下末尾是 0 的个数,不会。。。然后就抓了一个大佬问一哈,


但是不理解其中的原理,以后再说吧

#include"bits/stdc++.h"
#define out(x) cout<<#x<<"="<<x
using namespace std;
typedef long long LL;
LL prime[25]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
LL dfs(LL END,LL sta,LL ld,LL rd)
{
    if(sta==END)return 1;
    else if(sta>END)return 0;
    LL pos=(END)&(~(sta|ld|rd));
    LL ans=0; 
    while(pos)
    {
        LL t=pos&-pos;
        ans+=dfs(END,sta|t,(ld|t)<<1,(rd|t)>>1);
        pos-=t;
    }
    return ans;
}
LL solve(LL x,LL m)
{
    LL res=0;
    while(x)
    {
        res+=x/m;
        x/=m;
    }
    return res;
}
int main()
{
    map<LL,LL>F,vis;
    F[1]=1,F[2]=1,vis[1]=1;
    for(int i=3;;i++)
    {
        F[i]=F[i-1]+F[i-2];
        if(F[i]>1e18)break;
        vis[F[i]]=i;
    }
    LL X,M;
    while(cin>>X>>M)
    {
        if(vis[X])
        {
            LL ans=1e18; 
            for(int i=24;i>=0;i--)
            {
                if(M%prime[i]==0)
                {
                    LL cnt=0;
                     while(M%prime[i]==0)M/=prime[i],cnt++;
                    ans=min(ans,solve(X,prime[i])/cnt);
                }
            }
            cout<<ans<<endl;
        }
        else
        {
            X=X%min(13LL,M)+1;
            cout<<dfs((1<<X)-1,0,0,0)<<endl;
        }
    } 
}

E-面积

首先有一个“皮克定理”,就是说假如有一个多边形,他的所有顶点都在格点上,那么他的面积为:

S = n 1 + n 2 2 1

n 1 为多边形内部的格点数
n 2 为多边形边上的格点数

这道题的“最大生成图”,其实就是个格点多边形,而且内部没有格点,也就是 n 1 = 0 ,所以 n 2 = M N

据说又有一个定理:“波尔约-格维也纳定理”,大概就是说,任意一个多边形,都能够瞎几把拼接成另外一个多边形,只要他们的面积相等~

那么这道题就是看这个“最大生成图” 与 三角形 的面积是不相等了。。。

#include"bits/stdc++.h"
#define out(x) cout<<#x<<"="<<x
using namespace std;
typedef long long LL;
const LL maxn=1e5+5;
int main()
{
    double N,M,x1,x2,y1,y2;
    while(cin>>N>>M>>x1>>y1>>x2>>y2)
    {
        double S1=N*M/2-1,S2=1.0*abs(1.0*x1*y2-1.0*x2*y1)/2.0;
        if(abs(S1-S2)<1e-6)cout<<"Yes\n";
        else cout<<"No\n";

    }
}