题目描述

红晕爬上了白玫瑰的花瓣,花刺还没有到达夜莺的心脏,玫瑰的心依旧苍白如终年不化的积雪。由生命铸就的玫瑰不允许存在一丝一毫的瑕疵,假设玫瑰的一片花瓣可以抽象成一个点,一朵玫瑰我们用一个$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模拟测试]:夜鹰与玫瑰(数学)的更多相关文章

  1. [CSP-S模拟测试]:题(DP+数学)

    题目描述 出个题就好了.这就是出题人没有写题目背景的原因.你在平面直角坐标系上.你一开始位于$(0,0)$.每次可以在上/下/左/右四个方向中选一个走一步.即:从$(x,y)$走到$(x,y+1),( ...

  2. [CSP-S模拟测试]:C(倍增+数学)

    题目传送门(内部题152) 输入格式 第一行两个整数$N,Q$. 接下来一行$N$个整数,第$i$个为$a_i$. 接下来的$N-1$行,每行两个整数$u,v$.表示$u,v$之间有一条边. 接下来的 ...

  3. [CSP-S模拟测试]:B(DP+数学)

    题目传送门(内部题45) 输入格式 第一行$3$个整数$n,m,P$.第二行$m$个整数,表示$m$次询问. 输出格式 一行$m$个整数表示答案. 样例 样例输入1: 2 4 40 1 2 3 样例输 ...

  4. [CSP-S模拟测试]:物理课(数学)

    题目传送门(内部题144) 输入格式 从$physics.in$读入数据. 第一行一个数$T$,代表有$T$组数据.接下来$T$行每行$4$个浮点数,分别为$\theta,v,d,g$,保留到小数点后 ...

  5. [CSP-S模拟测试]:最大或(数学)

    题目传送门(内部题141) 输入格式 输入文件包含多组测试数据,第一行为一个正整数$T$,表示数据组数. 接下来$T$行,每行两个正整数$l,r$.数据保证$l\leqslant r$成立. 输出格式 ...

  6. [CSP-S模拟测试]:平方数(数学+哈希)

    题目传送门(内部题137) 输入格式 第一行,一个正整数$n$. 第二行$n$个正整数$a_1\sim a_n$. 输出格式 输出一个整数,为满足条件的二元组个数. 样例 样例输入: 51 2 3 4 ...

  7. [CSP-S模拟测试]:简单计算(数学)

    题目传送门(内部题104) 输入格式 第一行一个正整数$T$,表示该测试点内的数据组数,你需要对该测试点内的$T$组数据都分别给出正确的答案才能获得该测试点的分数. 接下来$T$组数据,每组数据一行两 ...

  8. [CSP-S模拟测试]:异或(数学)

    题目描述 给定$L,R$,我们希望你求出:$$\sum\limits_{i=L}^R\sum\limits_{j=L}^R(i\oplus j)$$其中这里的$\oplus$表示异或运算.答案对$10 ...

  9. [CSP-S模拟测试]:位运算(数学)

    题目传送门(内部题72) 输入格式 输入文件$bit.in$ 每个输入文件包含$T$组测试数据.输入文件的第一行为一个整数$T$,表示数据组数.接下来$T$行,每行表示一组测试数据每组测试数据包括三个 ...

随机推荐

  1. LOJ 2555 「CTSC2018」混合果汁——主席树

    题目:https://loj.ac/problem/2555 二分答案,在可以选的果汁中,从价格最小的开始选. 按价格排序,每次可以选的就是一个前缀.对序列建主席树,以价格为角标,维护体积和.体积*价 ...

  2. Sumdiv

    题目链接 题意:求a^b的所有约数之和mod9901. 思路:因为一个数A能够表示成多个素数的幂相乘的形式.即A=(a1^n1)*(a2^n2)*(a3^n3)...(am^nm).所以这个题就是要求 ...

  3. html中ul,ol和li的区别

    ul是无序列表,全称是unordered list,先来个例子:    ●张三    ●李四    ●王二    ●刘五   ol是有序列表 ,全称是ordered list,同样举个例子:  1.张 ...

  4. 测开之路三十九:js基础

    js的两种使用方式 第一种使用方式:单独写js文件 在static下新建一个js文件并写入内容 alert('这是一个弹窗'); 在html文件里面,用script标签引入 <script sr ...

  5. 测开之路十六:@classmethod与@staticmethod

    @classmethod 类方法 和属性一样,所有实例化的对象都共享类方法 @staticmethod 静态方法,可以理解为和类没有任何关系,只是放在了类里面 参数可以任意定义,根据自己的定义传参,也 ...

  6. 利用Graphziv帮助理解复杂的类层次关系

    最近在学习osg三维视景仿真平台,学习的过程中涉及到许多的类与类之间的继承和包含关系.在复杂点的例子中,许多的类和节点组合在一起,很容易让人迷失方向.在编译源代码的时候,无意间发现了Graphviz这 ...

  7. scrapy错误-[scrapy.core.scraper] ERROR: Spider error processing

    一.问题,就是我的callback没得回调函数 二:然后我查看源代码,发现: 三.我把解析页数的函数名设置为,def parse(self,response):  就没保错了 能运行成功 总结:在sp ...

  8. Ptyhon变量,常量,注释

    变量的命名规则: 1.变量由字母,数字,下划线搭配而成 2.变量不能以数字开头 3.变量也不能是Python的关键字. 4.变量不要有中文 5.名字要有意义 6.名字不要太长 变量的两种命名方式: 1 ...

  9. JQ的live学习

    $("#StartTime").live("blur keypress keyup",function(){ if($("#EndTime" ...

  10. ReactOS 无法显示中文的问题

    其实非常简单, 实际上是因为包里面没有中文字体,所以输出文字都是乱码, 去 https://svn.reactos.org/optional/ 这里,下载ttf字体文件, 把字体文件放到源码中 mod ...