2021-08-09

The 14th Jilin Provincial Collegiate Programming Contest

G.Matrix

Problem G. Matrix
Input file: standard input
Output file: standard output
Time limit: 1 second
Memory limit: 256 megabytes
Bob is playing a matrix game. He needs to deal with a matrix of n rows and m columns, satisfying the
properties below:
• Both rows and columns are numbered from 1
• All the elements in the matrix have only two values: 0 and 1
• All the elements equals 0 initally
To play the game, Bob can apply flip(i, j) operations to the matrix. This operation can flip all elements
whose row number is a multiple of i and column number is a multiple of j (flipping an element means
change its value from v to 1−v). Bob is very bold when playing games. He always performs flip operations
on all the positive integer pairs (i, j).
After finishing all the operations, Bob wants to know how many elements which equals 1 there are in the
matrix.
Input
The first line is a single number T, indicating the number of test cases.
In the following T lines, the i-th line contains two integers n, m, representing the number of rows and
columns of the i-th matrix, respectively.
It is guaranteed that 1 ≤ T ≤ 10 and 1 ≤ n, m ≤ 1018
.
Output
T lines, the i-th line a single integer - the answer of the i-th matrix.

Example

standard inputstandard output
2
1 11
2 31

题意:

给你一个矩阵的长和宽,每个格子起始都是0,遍历所有的格子,遍历到格子的坐标为(i,j),就将行为i的倍数,列为j的倍数的格子上的数字进行变化:如果原来是0,变成1,如果原来是1变成0,问你遍历完所有格子后,矩阵中1的个数是多少。

思路:

1.对于每个格子的而言,如果变化的次数为奇数,那么它最终显示的就是1,如果变化的次数为偶数则为0。
2.对于每个位置为(i,j)的格子而言,它变化的次数是i的因子个数乘以j的因子个数。
3.对于坐标而言,一个数当且仅当是某个数的平方数,他才会有奇数个因子,否则它有偶数个因子。
4.这题就转化为,矩阵中格子的横纵坐标为平方数的个数。
5.如何求?二分第一个小于等于长和宽的数相乘就是答案。

代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
long long a, b;
LL binary_search(LL a)
{
    LL l = 1, r = 1e9;
    while(l < r)
    {
        LL mid = l + r + 1  >> 1;
        if(mid * mid <= a) l = mid;
        else r = mid - 1;
    }
    return l;
}
void solve(){    
    cin >> a >> b;
   cout << binary_search(a) * binary_search(b) << endl;
}
int main()
{
    int _ = 1;
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    cin >> _;
    while(_ -- ){
        solve();
    }
// system("pause");
    return 0;
}


基础知识总结:
二分:
二分有两种情况:
二分左端点:

int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
    return l;
}

二分右端点:

int bsearch_2(int l, int r)
{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值