zoukankan      html  css  js  c++  java
  • CodeForces 1242D Number Discovery

    CodeForces 1242D Number Discovery

    https://codeforces.com/contest/1242/problem/D

    (T) 组数据,每组给出 (n,k) .现在要用如下方式生成一个无限大的序列 (s)

    (s) 初始为空,重复一下步骤

    • 选择前 (k) 个不曾出现在 (s) 中的正整数 (u_1,u_2,cdots,u_k)
    • (u_1,u_2,cdots,u_k,sum_{i=1}^k u_i) 按此顺序加入 (s)

    易证所有正整数只会在 (s) 中出现一次,求 (n)(s) 中的编号.

    (1 le k le 10^6,1 le n le 10^{18})

    Tutorial

    称所有以 (sum u_i) 的形式加入 (s) 的数为non-self数,以 (u_i) 的形式加入 (s) 的为self数.

    观察发现,若设 (I_i=[i(k^2+1)+1,(i+1)(k^2+1)]) ,即 (k^2+1) 的大小的每一块,那么每个 (I_i) 中,有且只有一个non-self数.

    考虑归纳法,对于 (I_0) 它显然只包含一个non-self数 (dfrac 12k(k+1)) .那么考虑对于 (I_i) 中的 (k^2) 个self数组成的 (k) 次求和

    [sum_{j=1}^k (i cdot (k^2+1)+tk+j) +offset = (k cdot i+t)(k^2+1) + dfrac {k(k+1)}{2}-t+offset ]

    其中 (t) 表示这是第 (t) 组求和, (offset) 表示 (I_i) 中的non-self数的影响,显然有 (0 le offset le k) ,所以发现其实第 (t) 组的求和决定了 (I_{i cdot k +t}) 中的non-self数.

    所以可以如此递归求解,得到 (n) 的所属的 (I_i) 的non-self数 (x) ,如果这个数为 (n) ,则答案为 ((i+1)(k+1)) ,否则设 (p=n-i-(x<n)) 表示 (n) 之前的self数,则答案为 (p+lfloor dfrac {p-1}k floor) .

    Code

    https://codeforces.com/contest/1242/submission/77266243

    #include <cstdio>
    #include <iostream>
    #define debug(...) fprintf(stderr,__VA_ARGS__)
    using namespace std;
    inline char nc()
    {
    	return getchar();
    	static char buf[100000],*l=buf,*r=buf;
    	return l==r&&(r=(l=buf)+fread(buf,1,100000,stdin),l==r)?EOF:*l++;
    }
    template<class T> void read(T &x)
    {
    	x=0; int f=1,ch=nc();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=nc();}
    	while(ch>='0'&&ch<='9'){x=x*10-'0'+ch;ch=nc();}
    	x*=f;
    }
    typedef long long ll;
    ll n,k;
    ll B;
    ll I0;
    int T;
    ll I(ll x)
    {
    	if(x==0) return I0;
    	ll i=x/k,t=x%k;
    	ll Ii=I(i);
    	ll l=i*B+t*k+1;
    	ll r=l+k-1;
    	ll Ix=(l+r)*(r-l+1)/2;
    	if(Ii<=l) Ix+=k;
    	else if(Ii<=r) Ix+=r-Ii+1;
    	return Ix;
    }
    int main()
    {
    	read(T);
    	for(int kase=1;kase<=T;++kase)
    	{
    		read(n),read(k);
    		B=k*k+1;
    		I0=k*(k+1)/2;
    		ll i=(n-1)/B;
    		ll Ii=I(i);
    		if(n==Ii) printf("%I64d
    ",(i+1)*(k+1));
    		else
    		{
    			ll p=n-i-(Ii<n);
    			printf("%I64d
    ",p+(p-1)/k);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    MyBatis 学习笔记
    JavaEE路径陷阱之getRealPath
    Java路径问题最终解决方案—可定位所有资源的相对路径寻址
    Hibernate4.3.10通过slf4j使用log4j
    Hibernate关联关系映射
    SpringMVC 学习笔记
    Spring 学习笔记
    Hibernate 学习笔记
    Struts2 学习笔记
    vue element tree组件,根据不同的状态显示不同的字体颜色
  • 原文地址:https://www.cnblogs.com/ljzalc1022/p/12966690.html
Copyright © 2011-2022 走看看