zoukankan      html  css  js  c++  java
  • 【题解】[AHOI2002] 网络传输 By 5ab as a juruo.

    题目

    题目来源:CCF 安徽省选 2002;

    评测地址:Luogu#2558

    题目描述

    在计算机网络中所有数据都是以二进制形式来传输的。但是在进行较大数据的传输时,直接使用该数的二进制形式加以传输则往往传输的位数过多。譬如要传输 (1024) 就需要 (11) 位二进制数。于是小可可提出了一种数据优化传输的设想,并打算对这一设想进行试验。

    该设想是:正整数的所有方幂以及任意多个互不相等的 (k) 的方幂之和排成一个递增数列 (left<a_k ight>),例如当 (k=3) 时,(left<a_k ight>) 的前 (7) 项为 (1)(即 (3^0))、 (3)(即 (3^1))、(4)(即 (3^0+3^1))、(9) (即 (3^2))、(10)(即 (3^0+3^2))、(12)(即 (3^1+3^2))、(13)(即 (3^0+3^1+3^2))。

    如果数 (d) 是数列 (left<a_k ight>) 中的第 (p) 项,则可以通过传送 (k)(p) 这两个数来表示数 (d)。由于 (k)(p) 这两个相对很小的数就可以表达出很大的数 ,因而理论上可以减少网络传输的位数。

    小可可现在请你编写程序把接收到的数 (k)(p) 所代表的数d计算出来。

    输入格式

    文件中以一行的形式存放了两个正整数 (k)(p)

    输出格式

    以一行的形式输出问题的解(解的位数不超过 (50) 位)。

    数据规模及约定

    评测时间限制 (1000 extrm{ms}),空间限制 (128 extrm{MiB})

    (1<kle 1024)(1le ple 1024)

    分析

    题意是说给你一个由 (k^n) 的和构成的 递增 数列 (left<t ight>),求出这个数列的第 (p) 项。

    观察这些和之间的大小关系,不难发现一个性质:(large{k^n>sumlimits_{i=1}^{n-1} k^i})

    [egin{aligned} sumlimits_{i=1}^{n-1} k^i & =dfrac{k^n-1}{k-1}\ & le k^n-1<k^n end{aligned} ]

    也就是说,所有加上了 (k^n) 的数必然比所有没有加上 (k^n) 的数(包括更大的数)要大。也就是说 (k^n) 的选与不选满足单调性。

    我们定义 (p=sumlimits_{i} a_i imes 2^i),即 (left<a ight>)(p) 的二进制表达。

    只需证明 (t_p=sumlimits_{i} a_i imes k^i) 即可。

    我们尝试用数学归纳法证明:初始,显然 (t_1=k)

    考虑 (t_v left(vin left[2^n,2^{n+1} ight) ight)),利用单调性,易得 (t_v) 必然选择了 (k^n)

    注意到这一段区间共有 (2^n) 个,而之前也有 (2^n) 个。根据单调性和数列定义,易得 (t_v=t_{v-2^n+1}+k^n),满足二进制。

    证明了这个性质,接下来只需要对 (p) 进行二进制分解,然后预处理出 (k^n),最后遍历一遍就可以得到答案。

    Code

    别忘了加上高精度哦!

    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int max_lgm = 12; // 最大的 n
    
    struct long_int // 高精度(主要码量来源 hh)
    {
    	typedef char B;
    	static const int max_n = 50;
    
    	B v[max_n+1]; // 奇怪的写法增加了(误
    	int len;
    
    	long_int() : len(0)
    	{
    		memset(v, 0, sizeof(v));
    	}
    
    	void assign(int n)
    	{
    		memset(v, 0, sizeof(v));
                len = 0;
    
    		while (n > 0)
    		{
    			v[len] = n % 10;
    			n /= 10, len++;
    		}
    	}
    
    	void operator+=(const long_int& a)
    	{
    		for (int i = 0; i <= len || i <= a.len; i++)
    		{
    			v[i+1] += (v[i] + a.v[i]) / 10;
    			v[i] = (v[i] + a.v[i]) % 10;
    		}
    
    		if (a.len > len)
    			len = a.len;
    		
    		while (!v[len])
    			len--;
    		
    		len++;
    	}
    
    	void operator*=(const long_int& a)
    	{
    		B tmp[max_n+1] = {};
    
    		for (int i = 0; i < a.len; i++)
    		{
    			for (int j = 0; j < len; j++)
    			{
    				tmp[i+j+1] += (tmp[i+j] + a.v[i] * v[j]) / 10;
    				tmp[i+j] = (tmp[i+j] + a.v[i] * v[j]) % 10;
    			}
    		}
    
    		len += a.len;
    		while (!tmp[len])
    			len--;
    		len++;
    
    		for (int i = 0; i < len; i++)
    			v[i] = tmp[i];
    	}
    
    	void out()
    	{
    		for (int i = len - 1; i >= 0; i--)
    			putchar('0' + v[i]);
    	}
    
    	void outln()
    	{
    		out();
    		putchar('
    ');
    	}
    
        void operator=(const long_int& a)
        {
            len = a.len;
    
            for (int i = 0; i < len; i++)
                v[i] = a.v[i];
        }
    };
    
    long_int pw[max_lgm];
    
    int main()
    {
    	int p, k;
    	long_int tmp;
    
    	scanf("%d%d", &p, &k);
    	
    	pw[0].assign(1); // 预处理
    	tmp.assign(p);
    	for (int i = 1; i < max_lgm; i++)
        {
            pw[i] = pw[i-1];
    		pw[i] *= tmp;
        }
    	
        /*
        tmp.outln();
        for (int i = 0; i < max_lgm; i++)
            pw[i].outln();
        */
        
    	tmp.assign(0);
    	for (int i = 1, j = 0; i <= k; i <<= 1, j++) // 二进制分解+统计答案
    		if (i & k)
    			tmp += pw[j];
    	
    	tmp.outln(); // 精准结束
    
    	return 0; // 等待的就是 AC 喽
    }
    
  • 相关阅读:
    C++拷贝构造函数(深拷贝,浅拷贝)
    c++ string assign =
    undefined与null的区别---js
    Cocos2d-x内存自动释放机制--透彻篇
    cocos2d-x 坐标系
    cocos-html5 JS 写法基础 语言核心
    selenium--更改标签的属性值
    selenium--高亮显示正在操作的元素
    selenium--页面元素是否可见和可操作
    selenium--拖拽页面元素
  • 原文地址:https://www.cnblogs.com/5ab-juruo/p/solution-ahoi2002_lg2558.html
Copyright © 2011-2022 走看看