zoukankan      html  css  js  c++  java
  • SNOI2020 LOJ3324 取石子

    题目传送门

    分析:
    不是很懂,一顿胡乱找规律2333
    先写个暴力,设(f[i][j])表示目前还有(i)个石子,目前这一步最多取(j)个,先手是否必胜
    看一下转移:

    [f[i][j]=![&_{k=1}^{j}f[i-k][2k]] ]

    不知道与和怎么写,直接写一个(&)顶一下吧2333
    光看这个式子就可以发现一些性质:如果(f[i][j])为必败态,那么(f[i][k](k<j))也一定必败
    那么设(a_i)表示使(f[i][a_i])为必败态的最大的值
    打表出来找一下规律。。。从(a_0)开始:
    (INF,0,1,2,0,4,0,1,7,0,1,2,0,12,0,1,2,0,4,0,1,20....)
    发现其中某一些(a_i=i-1),之间间隔的数字是整个数列的前缀的一部分
    (a_i=i-1)的数全部提出来。。。设第(i)个数为(g_i),从(g_0)开始
    (0,1,2,4,7,12,20,33....)
    发现(g_i=g_{i-1}+g_{i-2}+1)
    再算一下(g_i)之前每一个(g_j)的出现次数。。。(假设(i)为7)
    (13,8,5,3,2,1,1)
    发现是倒序的斐波那契数列
    规律就找到了。。。
    斐波那契数列和上面的(g)增长速度都是指数级别的
    单次复杂度为(O(logN))
    总复杂度(O(TlogN))
    这规律真离谱

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<iostream>
    #include<map>
    #include<string>
    
    #define maxn 100005
    #define INF (1ll<<60)
    
    using namespace std;
    
    inline long long getint()
    {
        long long num=0,flag=1;char c;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
        while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
        return num*flag;
    }
    
    long long k,N;
    long long f[maxn],fib[maxn],cnt;
    long long ans;
    
    inline void solve(int x)
    {
    	if(k>f[x])ans++;
    	for(int i=0;i<x;i++)if(k>f[i])ans+=fib[x-i];
    }
    
    int main()
    {
    	f[0]=0,f[1]=1,cnt=1,fib[0]=0,fib[1]=1;
    	while(1)
    	{
    		cnt++;
    		f[cnt]=f[cnt-1]+f[cnt-2]+1;
    		fib[cnt]=fib[cnt-1]+fib[cnt-2];
    		if(f[cnt]>INF)break;
    	}
    	int T=getint();
    	while(T--)
    	{
    		k=getint(),N=getint();ans=0;
    		if(N==1){printf("0
    ");continue;}
    		N-=2;
    		for(int i=cnt;i>=0;i--)if(N>=f[i])solve(i),N-=f[i]+1;
    		printf("%lld
    ",ans);
    	}
    }
    

  • 相关阅读:
    母爱——值得你用一生去回报
    cmd命令介绍
    对即将步入软件行业的师弟师妹们的忠告
    推荐4本c语言宝书
    不用判断语句如if,?:等来实现比较2个数
    javascript 浏览器不同的一个差异
    更新数据的经典代码
    允许 ASP.NET 服务器控件在 Page 中发出客户端脚本块的方法Page.RegisterClientScriptBlock 方法 [C#]
    使用多个表进行查询
    根据按钮的不同的CommandArgument处理每个按钮的单击事件的代码
  • 原文地址:https://www.cnblogs.com/Darknesses/p/13202928.html
Copyright © 2011-2022 走看看