[CSP-S模拟测试41]题解

Posted rorschach-xr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CSP-S模拟测试41]题解相关的知识,希望对你有一定的参考价值。

中间咕的几次考试就先咕着吧……

A.夜莺与玫瑰

枚举斜率。只考虑斜率为正且不平行于坐标轴的直线,最后把$ans\times 2$再$+1$即可。

首先肯定需要用$gcd(i,j)==1$确保斜率的唯一性,但由于题目中Deadline的定义是直线不是线段,所以一个方向只能有一条,需要去重。那么我们计算一条直线的贡献,当且仅当它和它的前驱线段在点阵内且后继线段不在点阵内。

暴力求解:$ans=\sum \limits_i=1^n-1 \sum \limits_j=1^m-1 [gcd(i,j)==1] ((n-i)\times(m-j)-\max (n-2i,0) \times \max (m-2j,0))$,时间复杂度$O(n^2 T)$。

尝试通过预处理降低每次询问的复杂度:计算对于每个$i$与它互质的$j$的前缀个数与前缀和,之后把柿子拆一下复杂度就变成$O(nT)$的了。

卡内存?值域不超过4000的数组为什么不用short呢?(滑稽

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int mod=(1<<30),N=4005;
typedef long long ll;
int n,m,T;
int sum[N][N];
short gcd[N][N],copr[N][N];
void work()

    scanf("%d%d",&n,&m);
    ll ans=0;
    for(int i=1;i<=n-1;i++)
    
        ll num1=1LL*(n-i)*(1LL*copr[i][m-1]*m-sum[i][m-1])%mod;
        if(n-2*i>0)num1=(num1-1LL*(n-2*i)*(1LL*m*copr[i][m/2]-2*sum[i][m/2])+mod)%mod;
        ans+=num1,ans%=mod;
    

    /*for(int i=1;i<=n-1;i++)
        for(int j=1;j<=m-1;j++)
            if(gcd(i,j)==1)ans+=(1LL*(n-i)*(m-j)-max(n-i*2,0LL)*max(m-j*2,0LL));*/
    printf("%lld\n",(ans*2%mod+1LL*n+m)%mod);


int main()

    scanf("%d",&T);
    gcd[1][1]=gcd[1][2]=gcd[2][1]=1;
    for(int i=1;i<=4000;i++)
        gcd[i][0]=i,gcd[i][1]=gcd[1][i]=1;
    for(int i=1;i<=4000;i++)
    
        for(int j=1;j<=4000;j++)
        
            gcd[i][j]=gcd[min(i,j)][max(i,j)%min(i,j)];
            copr[i][j]=copr[i][j-1],sum[i][j]=sum[i][j-1];
            if(gcd[i][j]==1)copr[i][j]++,sum[i][j]+=j;
            //if(i<=50&&j<=50)cout<<i<<‘ ‘<<j<<‘ ‘<<gcd[i][j]<<‘ ‘<<copr[i][j]<<‘ ‘<<sum[i][j]<<endl;
        
    

    while(T--)work();
    return 0;

 

以上是关于[CSP-S模拟测试41]题解的主要内容,如果未能解决你的问题,请参考以下文章

[CSP-S模拟测试59]题解

[CSP-S模拟测试53]题解

csp-s模拟测试61砖块, 数字,甜圈题解

[CSP-S模拟测试74]题解

[CSP-S模拟测试69]题解

[CSP-S模拟测试97]题解