codechef April challenge (2)(学习去优化提高效率)

Counting Matrices

Problem code: CNPIIM

此题逆向解决问题,先求出乘积为i的数对有多少个,到询问的时候直接输出就行了!

Lira loves Linear Algebra and she is especially keen about matrix :).

Today, she learnt some properties about matrices, namely, she learnt about what the trace of a matrix is, as her teacher gave her many exercises for her to practice.

As we know she is pretty clever, she rapidly came up with some definitions of her own and devised a somewhat harder version of the problem initially proposed by her teacher.

Namely, she defines a Positive Invertible Integer Matrix as being an invertible 2x2 matrix composed only of positive (i.e. greater than 0) integer elements and whose determinant is greater than 0.

Now, she is interested in counting how many such matrices are there, such that their trace is equal to N .

It's your turn to solve Lira's problem :D

Input

The first line of the input contains an integer T denoting the number of test cases. The description of T test cases follows.

Each test case consist of single integer N, the trace of the matrix.

Output

For each test case, output a single line containing the number of Positive Invertible Integer Matrices such that their trace is equal to N and dterminant is positive.

Constraints:

  • 1T50
  • 3N2500

 

Example

Input:
1
3

Output:
2	

Explanation

The only two matrices that exist with trace equal to 3 and that satisfy all the given conditions are:

#include<stdio.h>
#define N 2500
const int MAX=N*N/4;
int dp[MAX],num[MAX];
//计算乘积小于x的数对的个数
void unit()
{    //计算乘积为i的数对的对数,逆向得到存储在数组里
    int i;
     for(i=1;i<=MAX;i++)
        {
            for(int j=1;j<=MAX;j++)
            {
                if(i*j>MAX) break;
                dp[i*j]++;
            }
        }
       for(i=1;i<MAX;i++)
        {
            num[i]=num[i-1]+dp[i];
        }
}
int main()
{
   unit();
   int a1,t,n;
   scanf("%d",&t);
   for(;t>0;t--)
   {   long long  sum=0;
       scanf("%d",&n);
       for(a1=1;a1<=(n-1)/2;a1++)
       {
           int tri=a1*(n-a1);
           sum+=num[tri-1];
       }
       if(n%2!=0)  printf("%lld\n",2*sum);
       else   printf("%lld\n",sum*2+num[n/2*n/2-1]);

   }
   return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值