洛谷 AT249 紅茶(Tea)

洛谷 AT249 紅茶(Tea)

题目链接:洛谷 AT249 紅茶(Tea)

算法标签: 模拟二分

题目

题目描述

一天,(kagamiz) 一边喝红茶,一边尝试解答如下的问题:

当由两个正整数所组成的正整数组以如下方式排列时, ((m,n))是这个数列里的第几组?

((1,1),(2,1),(1,2),(3,1),(2,2),(1,3),(4,1),(3,2),(2,3),(1,4),(5,1),…)

这个问题对他来说太简单了,所以他更深入地考虑了以下这个问题:

当上述数列中的 (i) 个组为((a_i,b_i)),第 (j) 个组为((a_j,b_j))时, ((a_i+a_j,b_i+b_j))是这个数列里的第几组?

你的任务就是帮助他解答这个问题。

输入格式

输入仅一行,为两个正整数 (i,j)

输出格式

输出为一个正整数,表示当上述数列中的第(i)个组为((a_i,b_i)), 第(j)个组为((a_j,b_j))时, ((a_i+a_j,b_i+b_j))是这个数列里的第几组。

输入输出样例

输入 #1

1 1

输出 #1

5

输入 #2

3 2

输出 #2

13

输入 #3

114 514

输出 #3

1155

说明/提示

数据范围:

  • (i≥1,1≤j≤10^8),且(i,j)均为正整数。
  • (i,j) 可能相等。

题解:

首先这道题我们要看所给出的数对:

((1,1),(2,1),(1,2),(3,1),(2,2),(1,3),(4,1),(3,2),(2,3),(1,4),(5,1),…)

我们可以发现,和为(n)的数对共有(n - 1)对,所以可以根据这个规律来统计所询问为第几组。

之后继续观察,在每一个合为(n)的数对组中,第一位是从 (n - 1)(1) 递减的,而第二位则正好相反,从 (1)(n - 1)递增,这个可以统计为第几行(将所有和相等的数对看做一行)的第几个。

同样由于本题的数据范围 (1 ≤ j ≤ 10^8) ,显然我们暴力进行查询和求和是很受限制的(没有测过),所以我们选择使用等差数列求和二分答案的方式进行求解,具体代码实现如下:

long long getsum(ll q) // 等差数列求和
{
    return 1ll * ((1 + q) * q) / 2;
}
void find(long long q) // 二分查找答案
{
    ll l = 1, r = N + 1, mid;
    while(l < r)
    {
        mid = (l + r) >> 1;
        if (getsum(mid) >= q)
            r = mid;
        else 
            l = mid + 1;
    }
    yy = q - getsum(l - 1);
    xx = l - yy + 1;
}

AC代码

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 1e8 + 10;
typedef long long ll;
int xx, yy;
long long getsum(ll q)
{
    return 1ll * ((1 + q) * q) / 2;
}
void find(long long q)
{
    ll l = 1, r = N + 1, mid;
    while(l < r)
    {
        mid = (l + r) >> 1;
        if (getsum(mid) >= q)
            r = mid;
        else 
            l = mid + 1;
    }
    yy = q - getsum(l - 1);
    xx = l - yy + 1;
}
int main()
{
    ll x, y;
    scanf("%lld%lld", &x, &y);
    find(x);
    ll ax = xx, ay = yy;
    find(y);
    ll bx = xx, by = yy;
    ll qx = ax + bx, qy = ay + by;
    ll pos = qx + qy - 1;
    pos = getsum(pos - 1) + qy;
    printf("%lld
", pos);
    return 0;
}
原文地址:https://www.cnblogs.com/littleseven777/p/11845655.html