루오 구 AT249 홍차 (차) - 시뮬레이션, 두 지점

루오 구 AT249 홍차 (차)

주제 링크 : 루오 구 AT249 홍차 (차)

알고리즘 模拟태그 : ,二分

이름

제목 설명

어느 날, \ (kagamiz \) 다음 질문에 대답하는 동안, 차를 마시는 동안 :

두 개의 양의 정수로 구성 양수 이루어진 군 같은 방식으로 배열 될 때, (\ (\), N- m)의 처음 몇 세트의 열 수는 무엇입니까?

\ ((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는 \) 양의 정수이다.
  • \ (난, 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\n", pos);
    return 0;
}

추천

출처www.cnblogs.com/littleseven777/p/11845655.html