• [BZOJ4725][POI2017]Reprezentacje ró?nicowe


    4725: [POI2017]Reprezentacje ró?nicowe

    Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 122  Solved: 59 [Submit][Status][Discuss]

    Description

    给定一个数列a:
    当n<=2时,a[n]=n
    当n>2,且n是奇数时,a[n]=2a[n-1]
    当n>2,且n是偶数时,a[n]=a[n-1]+r[n-1]
    其中r[n-1]=mex(|a[i]-a[j]|)(1<=i<=j<=n-1),mex{S}表示最小的不在S集合里面的非负整数。
    数列a的前若干项依次为:1,2,4,8,16,21,42,51,102,112,224,235,470,486,972,990,1980。
    可以证明,对于任意正整数x,只存在唯一一对整数(p,q)满足x=a[p]-a[q],定义为repr(x)。
    比如repr(17)=(6,3),repr(18)=(16,15)。
    现有n个询问,每次给定一个正整数x,请求出repr(x)。

    Input

    第一行包含一个正整数n(1<=n<=10^5)。
    接下来n行,每行一个正整数x(1<=x<=10^9),表示一个询问。

    Output

    输出n行,每行两个正整数p,q,依次回答每个询问。

    Sample Input

    2
    17
    18

    Sample Output

    6 3
    16 15
     
    发现数列增长的很快
    然后把$10^9$以内的$a$全部打出来
    若一个$x$的值已经被减出来了就直接输出
    没有的话发现肯定是没打出来的且相邻的两项$a$差出来的
    然后根据那个$mex$的性质,计算一下还需要多少项即可
    #pragma GCC optimize("O2")
    #include <map>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    char buf[10000000], *ptr = buf - 1;
    inline int readint(){
        int n = 0;
        while(*++ptr < '0' || *ptr > '9');
        while(*ptr <= '9' && *ptr >= '0') n = (n << 1) + (n << 3) + (*ptr++ & 15);
        return n;
    }
    int a[100], b[1000000], cnt = 0;
    map<int, pair<int, int> > mp;
    int main(){
        fread(buf, sizeof(char), sizeof(buf), stdin);
        mp.clear();
        a[1] = 1;
        a[2] = 2;
        mp[1] = make_pair(2, 1);
        int last, tot;
        for(last = 1, tot = 3; ; tot++){
            if(tot & 1) a[tot] = a[tot - 1] + a[tot - 1];
            else{
                while(mp.count(last)) last++;
                a[tot] = a[tot - 1] + last;
            }
            for(int j = 1; j < tot; j++)
                if(!mp.count(a[tot] - a[j]))
                    mp[a[tot] - a[j]] = make_pair(tot, j);
            if(!(tot & 1) && a[tot] > 1000000000) break;
        }
        map<int, pair<int, int> >::iterator it;
        for(it = mp.begin(); it != mp.end(); ++it)
            b[++cnt] = it -> first;
        int n = readint(), x, y;
        while(n--){
            x = readint();
            if(mp.count(x)) printf("%d %d
    ", mp[x].first, mp[x].second);
            else{
                y = lower_bound(b + 1, b + cnt + 1, x) - (b + 1);
                printf("%d %d
    ", tot + (x - y) * 2, tot + (x - y) * 2 - 1);
            }
        }
        return 0;
    }
  • 相关阅读:
    821. 字符的最短距离
    1122. 数组的相对排序
    258. 各位相加
    C++常见问题之二#define使用中的陷阱
    python进阶二_基本数据类型与操作
    DirectX10一变换(三)
    Android中编译工具链的改动----LLVM份量的增加
    DirectX10一矩阵代数(二)
    DirectX10一向量代数(一)
    基于asp.net + easyui框架,一步步学习easyui-datagrid——实现添加、编辑、删除(三)
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7636801.html
Copyright © 2020-2023  润新知