zoukankan      html  css  js  c++  java
  • CF1242D. Number Discovery

    题目大意


    题解

    神仙题

    直接在原序列上不好搞,考虑按照值顺序考虑,设直接加的为一类数,求和加进去的为二类数

    有一个牛比结论:([i(k^2+1)+1,(i+1)(k^2+1)])中存在恰好一个二类数(i从0开始)

    先假设这个是对的,当前已知第i段的数为x,考虑求第ki+t段的x',初始段为0目标段为(n-1)/(k^2+1),初始x为k(k+1)/2

    (x'=sum_{j=1}^i i(k^2+1)+kt+j+[...>=x])

    因为每段长为k^2+1,所以会在后面产生恰好k个二类数,由于不知道前面的二类数所以只考虑本段产生的

    展开得到(x'=ik(k^2+1)+k^2t+k(k+1)/2+(0 ext{~}k))

    考虑第ki+t段的范围,发现当k>=2时即使后面的0~t是最坏情况也刚好在范围内,所以不展开了(

    于是可以算出x',后面的考虑区间与x的关系可以求出

    最后根据n和x的大小关系讨论即可O(log)求解

    code

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define min(a,b) (a<b?a:b)
    #define max(a,b) (a>b?a:b)
    #define ll long long
    //#define file
    using namespace std;
    
    int a[101],T,i,j,k,l,tot;
    ll s,n,K,x,I,ans;
    
    void turn(ll t) {x=I*K*(K*K+1)+K*K*t+(1+K)*K/2+max(I*(K*K+1)+K*t+K-max(x,I*(K*K+1)+K*t+1)+1,0);}
    
    int main()
    {
    	#ifdef file
    	freopen("CF1242D.in","r",stdin);
    	#endif
    	
    	scanf("%d",&T);
    	for (;T;--T)
    	{
    		scanf("%lld%lld",&n,&K),s=(n-1)/(K*K+1);
    		x=s,tot=0;
    		while (x) a[++tot]=x%K,x/=K;
    		
    		I=0,x=K*(K+1)/2;
    		fd(i,tot,1)
    		turn(a[i]),I=I*K+a[i];
    		if (n==x)
    		ans=(s+1)*(K+1);
    		else
    		ans=n-s-(n>=x)+(n-s-(n>=x)-1)/K;
    		printf("%lld
    ",ans);
    	}
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    笔记本电脑处理器(CPU)性能排行榜
    SQL Server 2008管理工具出现 远程过程调用失败0x800706be解决方法
    Installshield使用教程
    区间DP--凸多边形三角剖分
    树形DP--codevs 1380 没有上司的舞会
    DP练习 巡逻
    DP练习 最长上升子序列nlogn解法
    线段树 求区间连乘——hdu 3074 Multiply game
    模拟算法+栈 HDU 1022
    并查集--CSUOJ 1601 War
  • 原文地址:https://www.cnblogs.com/gmh77/p/13810979.html
Copyright © 2011-2022 走看看