[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$行,每行表示一组测试数据每组测试数据包括三个 ...
随机推荐
- Pasha and Tea
Pasha and Tea time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- eclipse项目(java project)如何导入jar包的解决方案列表?
右键项目-properties-java build path(左侧菜单)-选择libraries 有两种方式,导入jar包实际上就是建立一种链接,并不是copy式的导入 一.导入外部包,add ex ...
- Mac上VMWare Fusion配置多台cent os
一.创建虚拟机(准备工作) 1.使用VMWare Fusion 创建第一台虚拟机 2.选择操作系统(本次使用的是使用cent os 6.5 64bit 系统) 3.选择磁盘大小(楼主mac上的磁盘大小 ...
- spark sql correlated scalar subqueries must be aggregated 错误解决
最近在客户中使用spark sql 做一些表报处理,但是在做数据关联时,老是遇到 “correlated scalar subqueries must be aggregated” 错误 举一个例子, ...
- centos7下zookeeper安装配置
1.下载zookeeper文件 cd /opt/ wget http://mirrors.hust.edu.cn/apache/zookeeper/stable/zookeeper-3.4.9.tar ...
- Bootstrap 学习笔记2 栅格系统 辅助类下拉框
辅助类和响应式工具: 颜色和字体相同 响应式工具: 图标菜单按钮组件: btn-group 按钮式下拉菜单
- js中的attributes和Attribute的用法和区别。
一:Attribute的几种用法和含义(attributes和Attribute都是用来操作属性的) getAttribute:获取某一个属性的值: setAttribute:建立一个属性,并同时给属 ...
- 使用UI Automation实现自动化测试--5-7
使用UI Automation实现自动化测试--5 (Winfrom和WPF中弹出和关闭对话框的不同处理方式) 在使用UI Automation对Winform和WPF的程序测试中发现有一些不同的地方 ...
- UVA1629_Cake slicing
Cake slicing 给你一个矩形大小,和每个樱桃的坐标,现在让你去切使得切之后的小矩形包含一个樱桃,每次切的代价是切痕的长度,问你最小代价是多少 思路: 首先要明白一点,不能切除一个不含樱桃的矩 ...
- 五、hibernate表与表之间的关系(一对多关系)
数据库表与表之间的关系 一对多:一个学校可以有多个学生,一个学生只能有一个学校 多对多:一个学生可以有多个老师,一个老师可以教多个学生 一对一:一个人只能有一个身份证号,一个身份证号只能找到一个人 一 ...