【GDOI2016模拟7.10】Banner
来源:互联网 发布:傲剑境界升级数据 编辑:程序博客网 时间:2024/06/03 22:57
Description
给定一个网格,左下角为(0,0),右上角为(n,m),求有多少种方案可以选择两个整点点,使得这两个点的连线不经过其他整点并且长度在l~r之间。答案对p取模。
n,m<=10^5,1<=l<=r<=1.5*10^4,p<=10^9
Solution
首先,让我们来想一想,怎样的两点连线不经过其他点呢?
构成直角三角形,两条直角边长互质!
于是题目就相当于求
考虑优化
发现那一坨东西可以用容斥原理搞出来。
直接暴力容斥就好了,因为i的质因数个数不会特别多。
%%%Yves___的神奇容斥法(涨姿势了)
注意边界。
Code
#include<cstdio>#include<cmath>#include<algorithm>#define fo(i,a,b) for(ll i=a;i<=b;i++)#define sqr(x) (x)*(x)using namespace std;typedef long long ll;ll n,m,l,r,p,ans,a[20];int gcd(int x,int y) {return (y)?gcd(y,x%y):x;}ll sum(ll x) {return x*(x+1)/2%p;}ll calc(ll x) { if (x<0) return 0; ll ans=((m+1)*x%p-sum(x)+p)%p; fo(i,1,(1<<a[0])-1) { ll bz=1,k=1; fo(j,1,a[0]) if (i&(1<<(j-1))) bz=-bz,k*=a[j]; if (k>x) continue; ans=(ans+bz*(((m+1)*(x/k)%p-k*sum(x/k)%p)+p)%p+p)%p; } return ans;}int main() { scanf("%lld%lld%lld%lld%lld",&n,&m,&l,&r,&p); if (l<=1) ans=((n+1)*m%p+n*(m+1)%p)%p; fo(i,1,min(n,r)) { ll le,ri;a[0]=0;ll k=i; fo(j,2,ll(sqrt(i))) { if (!(k%j)) a[++a[0]]=j; while (!(k%j)) k/=j; } if (k!=1) a[++a[0]]=k; if (i<=l) le=max(ll(ceil(sqrt(sqr(l)-sqr(i)))),ll(1));else le=1; ri=min(m,ll(sqrt(sqr(r)-sqr(i)))); if (le<=ri) ans=(ans+(calc(ri)-calc(le-1)+p)%p*(n-i+1)*2%p)%p; } printf("%lld",ans);}
(好烦哪!!好丑啊!!)
1 0
- 【GDOI2016模拟7.10】Banner
- GDOI2016模拟8.10踢足球
- GDOI2016模拟8.8旋转
- GDOI2016模拟8.8处理器
- GDOI2016模拟8.13总结
- GDOI2016模拟8.14总结
- GDOI2016模拟8.14数树数
- GDOI2016模拟8.15总结
- GDOI2016模拟8.15蜘蛛侠
- GDOI2016模拟8.15送票
- GDOI2016模拟8.16总结
- GDOI2016模拟8.16帮派
- GDOI2016模拟8.18总结
- GDOI2016模拟8.18蜡笔
- GDOI2016模拟8.18的士
- GDOI2016模拟8.18解密
- GDOI2016模拟8.19总结
- GDOI2016模拟8.19数学
- Circumventing Group Policy Settings
- 若无心事挂枝头,便是人间好时节
- go语言学习心得
- test
- 网站分页前后台代码
- 【GDOI2016模拟7.10】Banner
- C++ 指针与const的组合复习
- IOC(控制反转,反向控制)
- UVA 12664 Interesting Calculator
- ListView in fragment 列表视图的使用
- C++, ID、指针、handle (void *)的区别
- 51nod1432 独木舟
- linux下定时器函数
- BZOJ1984月下“毛景树”