루오 구 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;
}