[CSP-S模拟测试]:夜鹰与玫瑰(数学)
题目描述
红晕爬上了白玫瑰的花瓣,花刺还没有到达夜莺的心脏,玫瑰的心依旧苍白如终年不化的积雪。由生命铸就的玫瑰不允许存在一丝一毫的瑕疵,假设玫瑰的一片花瓣可以抽象成一个点,一朵玫瑰我们用一个$N\times M$的点阵表示,任意选择其中两个点可以构造出一条$"dead\ line"$。我们需要知道,对于一朵玫瑰,有多少条不同的$"dead\ line"$。两
条$"dead\ line"$不同当且仅当它们不重合,即两条$"dead\ line"$的交点数是有穷的。
输入格式
第一行一个正整数$T$表示数据组数,接下来$T$行,每行两个正整数$N,M$,意义如题。
输出格式
共$T$行,表示这一组数据的答案,答案对$2^{30}$取模。
样例
样例输入:
4
22
7 10
23 34
100 100
样例输出:
6
1111
139395
22791174
数据范围与提示
对于$40%$的数据T≤5,2≤N,M≤40$
对于另外$20%的数据T≤10,2≤N,M≤200$
对于$100%$的数据$T≤10,000,2≤N,M≤4,000$
题解
首先,解释一下题意,$"dead\ line"$是直线,而不是线段。
也就是对于下面这张图,所有的线段是:

所以,我们先来考虑朴素算法。
那么我们发现,只有那些长和宽的$GCD$为$1$的矩形才有可能对答案造成贡献。
但是这样会有重复的,所以我们还要减去$GCD$为$2$的矩形的数量。
也就是说答案是:$\sum \limits_{i=1}^{n-1}\sum \limits_{j=1}^{m-1}[gcd(i,j)=1]((n-i)(m-j)-\max(n-2\times i,0)\times \max(m-2\times j,0))$
$60\%$算法:
每次暴力求上面那个式子。
时间复杂度:$\Theta(T\times n\times m)$。
期望得分:$60$分。
实际得分:$60$分。
$100\%$算法$1$:
通过前缀和预处理出来答案,然后$\Theta(1)$查询即可。
时间复杂度:$\Theta(T+4000\times 4000)$。
期望得分:$100$分。
实际得分:$100$分。
$100\%$算法$2$:
我也不太会,大概讲两句:
化简?上面那个式子:
$\sum \limits_{i=1}^{n-1}\sum \limits_{j=1}^{m-1}[gcd(i,j)=1]((n-i)(m-j)-\max(n-2\times i,0)\times \max(m-2\times j,0)) \\ =\sum \limits_{i=1}^{n-1}\sum \limits_{j=1}^{m-1}\sum \limits_{d|gcd(i,j)}\mu (d)\times ((n-i)(m-j)-\max(n-2\times i,0)\times \max(m-2\times j,0)) \\ =\sum \limits_{d=1}{n-1}\mu (d)\times \sum \limits_{i=1}^{\left \lfloor \dfrac{n-1}{d} \right \rfloor}\sum \limits_{j=1}^{\left \lfloor \dfrac{m-1}{d} \right \rfloor}\sum \limits_{x=1}^{n-i\times d}\sum \limits_{y=1}^{m-j\times d}[x\leqslant i\times d\ or\ y\leqslant j\times d] \\ =\sum \limits_{d=1}^{n-1}\mu (d)\times \sum \limits_{i=1}^{\left \lfloor \dfrac{n-1}{d} \right \rfloor}\sum \limits_{j=1}^{\left \lfloor \dfrac{m-1}{d} \right \rfloor}(\sum \limits_{x=1}^{n-i\times d}[x\leqslant i\times d]\times (m-j\times d)) \\ +(\sum \limits_{y=1}^{m-j\times d}[y\leqslant j\times d]\times (n-i\times d)) \\ -(\sum \limits_{x=1}^{n-i\times d}\sum \limits_{y=1}^{m-i\times d}[x\leqslant i\times d\ and\ y\leqslant j\times d]) \\ =\sum \limits_{d=1}^{n-1}\mu (d)\times (\sum \limits_{i=1}^{\left \lfloor \dfrac{n-1}{d}\right \rfloor}\sum \limits_{x=1}^{n-i\times d}[x\leqslant i\times d]\times \sum \limits_{j=1}^{\left \lfloor \dfrac{m-1}{d}\right \rfloor}(m-j\times d)) \\ +(\sum \limits_{j=1}^{\left \lfloor \dfrac{m-1}{d} \right \rfloor}\sum \limits_{y=1}^{m-j\times d}[y\leqslant j\times d]\times \sum \limits_{i=1}^{\left \lfloor \dfrac{n-1}{d}\right \rfloor}(n-i\times d)) \\ -\sum \limits_{i=1}^{\left \lfloor \dfrac{n-1}{d}\right \rfloor}\sum \limits_{x=1}^{n-i\times d}[x\leqslant i\times d]\times \sum \limits_{j=1}^{\left \lfloor \dfrac{m-1}{d}\right \rfloor}\sum \limits_{y=1}^{m-j\times d}[y\leqslant j\times d])$
希望我上面那么长的$\LaTeX$没有打错吧,毕竟它……

时间复杂度:$\Theta(T\times n)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
$60\%$算法:
#include<bits/stdc++.h>
using namespace std;
int n,m;
unsigned int ans;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
ans=0;
for(int i=1;i<n;i++)
for(int j=1;j<m;j++)
if(__gcd(i,j)==1)
ans+=(n-i)*(m-j)-(max((n-(i<<1)),0)*max(m-(j<<1),0));
printf("%d\n",(n+m+(ans<<1))&1073741823);
}
return 0;
}
$100\%$算法$1$:
#include<bits/stdc++.h>
using namespace std;
int n,m;
pair<unsigned int,unsigned int> s[4001][4001];
int main()
{
for(int i=1;i<=4000;i++)
for(int j=1;j<=4000;j++)
{
s[i][j].first=(s[i-1][j].first+s[i][j-1].first-s[i-1][j-1].first+(__gcd(i,j)==1))&1073741823;
s[i][j].second=(s[i-1][j].second+s[i][j-1].second-s[i-1][j-1].second+s[i][j].first-s[i>>1][j>>1].first)&1073741823;
}
int T;scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
printf("%d\n",(n+m+(s[n-1][m-1].second<<1))&1073741823);
}
return 0;
}
$100\%$算法$2$:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int phi[4001],mu[4001];
bool vis[4001];
unsigned int ans;
void pre_work()
{
mu[1]=1;
for(int i=2;i<=4000;i++)
{
if(!vis[i]){phi[++phi[0]]=i;mu[i]=-1;}
for(int j=1;j<=phi[0];j++)
{
if(i*phi[j]>4000)break;
vis[i*phi[j]]=1;
if(!(i%phi[j])){mu[i*phi[j]]=0;break;}
mu[i*phi[j]]=-mu[i];
}
}
}
int main()
{
pre_work();
int T;scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
ans=0;
for(int i=1;i<n;i++)
ans+=2*mu[i]*(((n/(2*i)+1)*(n/(2*i))*i/2+n*((n-1)/i-n/(2*i))-((n-1)/i+n/(2*i)+1)*((n-1)/i-n/(2*i))*i/2)*(m*((m-1)/i)-((m-1)/i)*((m-1)/i+1)*i/2)+((m/(i*2)+1)*(m/(i*2))*i/2+m*((m-1)/i-m/(i*2))-((m-1)/i+m/(i*2)+1)*((m-1)/i-m/(i*2))*i/2)*(n*((n-1)/i)-((n-1)/i)*((n-1)/i+1)*i/2)-((n/(2*i)+1)*(n/(2*i))*i/2+n*((n-1)/i-n/(2*i))-((n-1)/i+n/(2*i)+1)*((n-1)/i-n/(2*i))*i/2)*((m/(i*2)+1)*(m/(i*2))*i/2+m*((m-1)/i-m/(i*2))-((m-1)/i+m/(i*2)+1)*((m-1)/i-m/(i*2))*i/2));
printf("%d\n",(n+m+ans)&1073741823);
}
return 0;
}
rp++
[CSP-S模拟测试]:夜鹰与玫瑰(数学)的更多相关文章
- [CSP-S模拟测试]:题(DP+数学)
题目描述 出个题就好了.这就是出题人没有写题目背景的原因.你在平面直角坐标系上.你一开始位于$(0,0)$.每次可以在上/下/左/右四个方向中选一个走一步.即:从$(x,y)$走到$(x,y+1),( ...
- [CSP-S模拟测试]:C(倍增+数学)
题目传送门(内部题152) 输入格式 第一行两个整数$N,Q$. 接下来一行$N$个整数,第$i$个为$a_i$. 接下来的$N-1$行,每行两个整数$u,v$.表示$u,v$之间有一条边. 接下来的 ...
- [CSP-S模拟测试]:B(DP+数学)
题目传送门(内部题45) 输入格式 第一行$3$个整数$n,m,P$.第二行$m$个整数,表示$m$次询问. 输出格式 一行$m$个整数表示答案. 样例 样例输入1: 2 4 40 1 2 3 样例输 ...
- [CSP-S模拟测试]:物理课(数学)
题目传送门(内部题144) 输入格式 从$physics.in$读入数据. 第一行一个数$T$,代表有$T$组数据.接下来$T$行每行$4$个浮点数,分别为$\theta,v,d,g$,保留到小数点后 ...
- [CSP-S模拟测试]:最大或(数学)
题目传送门(内部题141) 输入格式 输入文件包含多组测试数据,第一行为一个正整数$T$,表示数据组数. 接下来$T$行,每行两个正整数$l,r$.数据保证$l\leqslant r$成立. 输出格式 ...
- [CSP-S模拟测试]:平方数(数学+哈希)
题目传送门(内部题137) 输入格式 第一行,一个正整数$n$. 第二行$n$个正整数$a_1\sim a_n$. 输出格式 输出一个整数,为满足条件的二元组个数. 样例 样例输入: 51 2 3 4 ...
- [CSP-S模拟测试]:简单计算(数学)
题目传送门(内部题104) 输入格式 第一行一个正整数$T$,表示该测试点内的数据组数,你需要对该测试点内的$T$组数据都分别给出正确的答案才能获得该测试点的分数. 接下来$T$组数据,每组数据一行两 ...
- [CSP-S模拟测试]:异或(数学)
题目描述 给定$L,R$,我们希望你求出:$$\sum\limits_{i=L}^R\sum\limits_{j=L}^R(i\oplus j)$$其中这里的$\oplus$表示异或运算.答案对$10 ...
- [CSP-S模拟测试]:位运算(数学)
题目传送门(内部题72) 输入格式 输入文件$bit.in$ 每个输入文件包含$T$组测试数据.输入文件的第一行为一个整数$T$,表示数据组数.接下来$T$行,每行表示一组测试数据每组测试数据包括三个 ...
随机推荐
- ini操作
关于C#操作INI文件的总结 INI文件其实是一种具有特定结构的文本文件,它的构成分为三部分,结构如下: [Section1] key = value2 key = value2 …… [Sectio ...
- delphi 使用 InputBox、InputQuery 的启发
使用 InputBox.InputQuery 的启发 看了 InputBox.InputQuery 函数实现的源码, 有些收获与心得... ------------------------------ ...
- 获取数组NSArray元素的className
正确读取NSArray里面元素的Class类型的方法 object_getClass(columnsArray.firstObject) 错误的方法是 [columnsArray.firstObjec ...
- ansible控制winserver笔记
原文地址: https://www.cnblogs.com/kingleft/p/6391652.html 环境描述: ansible控制远程windows .系统必须是sp1 .安装framewor ...
- SharePoint 2013中PerformancePoint仪表板设计器连接Analysis Services 2012的问题
在SharePoint 2013的PerformancePoint仪表板设计器在创建链接到AnalysisServices 2012的数据链接的时候,数据库列表无法获取服务器上的数据库.这个问题挺让人 ...
- Python 多进程异常处理
前言 最近项目用到了Python作为网站的前端,使用的框架是基于线程池的Cherrypy,但是前端依然有一些比较‘重’的模块.由于python的多线程无法很好的利用多核的性质,所以觉得把这些比较‘重’ ...
- 自定义实现字符串string的接口
用char*管理String类的内存,new动态分配,在析构函数中delete char*指向的new出来的内存,一个string类需要实现那些接口可参考标准库里的string: http://ww ...
- pip安装第三方库报错Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None))...
pip安装第三方库时报错Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None))...,详细报错见下 ...
- 组件化框架设计之阿里巴巴开源路由框架——ARouter原理分析(一)
阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 背景 当项目的业务越来越复杂,业务线越来越多的时候,就需要按照业 ...
- 搭建git服务器遇到的问题
1.错误提示: remote: error: insufficient permission for adding an object to repository database ./objects ...