Codeforces Gym 100425D D - Toll Road 找规律

D - Toll Road
Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87493#problem/D

Description

Exactly N years ago, a new highway between two major cities was built. The highway runs from west to east. It was planned as one big segment of a toll road. However, new highway was not popular: drivers still used free roads.

After analyzing the situation, the administration decided to perform a marketing trick to increase the popularity of the new highway.

The highway was divided into segments. Initially, there was only one segment. Every odd year, each of the existing segments was divided into two new segments with lengths divided as X: Y. This means that the length of the western segment relates to the length of the eastern segment as X relates to Y. Every even year, each of the existing segments was also divided into two new segments, but this time, the ratio was Y: X. After each division, the first of the two resulting segments was declared a free road and the second one a toll road. Each year, the segments are numbered from 1 from west to east. For simplicity, X and Y are positive integers which sum up to exactly 100.

As a result, the administration was able to significantly increase the income: the drivers started to drive on free segments and did not dare to turn away at the sight of the next toll segment. But after N years, the plan of the highway became so complex that it is now hard to calculate the exact lengths of the segments.

Knowing the total length of the highway P, one can calculate the length Lk of the segment with number k using the formula

Lk = P × (X / 100)Ak × (Y / 100)Bk

for some integers Ak and Bk. Here, Ak is the number of years in which, during the division, this segment was in the part proportional toX, and Bk is the number of years when it was in the part proportional to Y.

You need to answer to the queries containing numbers Ki of segments. To answer each query, you must print the values of Aki and Bkifor the corresponding segment.

 

Input

The first line of the input contains three integers: the number of years N (1 ≤ N ≤ 1018) that have elapsed since the highway was built, followed by the percentages X and Y (1 ≤ X, Y ≤ 99, X + Y = 100) used each year to divide the segments.

The second line contains one integer: the number of queries Q (1 ≤ Q ≤ 104).

The following Q lines contain queries. Each query is an integer Ki (1 ≤ Ki ≤ 1018), the number of some segment. It is guaranteed that the segment with such number exists.

Output

For each query, print two integers  Aki and Bki on a separate line.

Sample Input

3 25 75 4
1
3
5
8

Sample Output

2 1
3 0
1 2
1 2

HINT

 

题意

前面全是废话

给你一个二叉树,第i层,第k个节点,如果(i+k)%2==0,那么这个节点就是A,否则节点就是B

Q次询问,每次问你第n层的第x节点,如果一直往上面爬,爬到第1层第1个节点,一共经历了几次A,几次B

题解

首先O(层数)的做法很明显是不可行的,应该要O(log)的,很容易发现,往上面爬和在同层次往左边爬是一样的

所以我们log爬到同层的第一个,然后再O(1)计算就好了

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <string>
#include <ctime>
#include <list>
#include <bitset>
typedef unsigned char byte;
#define pb push_back
#define input_fast std::ios::sync_with_stdio(false);std::cin.tie(0)
#define local freopen("in.txt","r",stdin)
#define pi acos(-1)

using namespace std;

int C(long long x,long long y)
{
    if(x%2==1)
    {
        if(y%2==1)
            return 1;
        else
            return 2;
    }
    else
    {
        if(y%2==1)
            return 2;
        else
            return 1;
    }
}
int main()
{
    long long n;
    long x1,x2,q;
    cin>>n>>x1>>x2>>q;
    for(int i=0;i<q;i++)
    {
        long long t1 = n;
        long long t2;
        scanf("%lld",&t2);
        long long ans1=0,ans2=0;
        while(1)
        {
            if(C(t1,t2)==1)
                ans1++;
            else
                ans2++;
            if(t2==1LL||t1==1LL)
                break;
            t2=(t2+1LL)/2LL;
            t1--;
        }
        t1--;
        if(t1!=0)
        {
            ans1+=t1/2LL;
            ans2+=t1/2LL;
            if(t1%2LL==1LL)
            {
                if(C(t1,t2)==1)
                    ans1++;
                else
                    ans2++;
            }

        }
        printf("%lld %lld\n",ans1,ans2);
    }
}

 

转载于:https://www.cnblogs.com/qscqesze/p/4725325.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值