zoukankan      html  css  js  c++  java
  • [JZOJ2700] 【GDKOI2012模拟02.01】数字

    题目

    在这里插入图片描述

    题目大意

    其实这题的题目大意非常简练,所以我认为我不用解释了。


    思考历程

    首先乱推了一波,然后什么东西都没有发现。
    于是想想D(i)D(i)的性质。
    我发现,由于每次是将各位上的数字相加。所以最多操作三次。
    本来是一个很大的数,然后缩小成百位数,然后缩成十位数,最后缩成个位数。
    我想,既然缩小一次就成了百位数了,所以,为什么不直接把百位数的表打出来,然后再继续推式子呢?
    然后我就把表打了出来。
    于是我就发现,我前面的想法尽是没用的……
    因为我发现了一个显而易见的规律:D(i)=(i1)mod  9+1D(i)=(i-1) mod 9+1
    这个规律可以感性理解,也可以理性证明,反正很简单,我就不说了。
    所以说,一个“被喜欢的数”就是能被x((x1)mod  9+1)x*((x-1)mod 9+1)表示的数。
    接下来就开始了我的瞎搞历程(提醒一下,正确性有误……)
    由于D(x)<=9D(x)<=9,不妨枚举D(x)D(x),设为jj
    设现在的数为ii。显然,如果要成立,首先要满足imod  j=0i mod j=0
    然后乱推:(ij1)mod  9+1=jleft(frac{i}{j}-1 ight) mod 9+1 =j
    所以(ij1)mod  9=j1left(frac{i}{j}-1 ight) mod 9=j-1
    由于j1<9j-1< 9,所以ij1j1(mod  9)frac{i}{j}-1 equiv j-1 (mod 9),所以ijj(mod  9)frac{i}{j} equiv j (mod 9)
    然后就是最尴尬的步骤:ij2(mod  9)iequiv j^2(mod 9)
    所以说,如果ii满足条件,必定有一个jj使得imod  j=0i mod j=0ij2(mod  9)iequiv j^2(mod 9)
    哈,这东西好像可以DP!
    fi,j,kf_{i,j,k}表示到第ii位,模25202520的余数为jj,第ii位上的值为kk的数的个数。
    252025201199的最小公倍数)
    按照之前推出来的条件,我们可以发现它是否为“被喜欢的数”只和jj有关。
    那我就可以愉快地数位DP了。

    然而现实是残酷的……
    WA了……
    后来推了好久,我发现原来是上面的一步出现了问题:
    我们知道ijj(mod  9)frac{i}{j} equiv j (mod 9),可以推出ij2(mod  9)iequiv j^2(mod 9)。可是后者不一定推出前者。
    因为99不是质数……
    不过如果只有这点错误,随便改一改那似乎也是可以过得去的。
    然后我就发现原来还是需要判重!
    怎么判?数位DP怎么判?判不了啊!

    XC说,今天除了第一题之外,其他的题还是很有难度的。
    除了第一题!!!!!!


    正解

    先说一个别人家的正解(当然我不懂是为什么):
    就是打一波表,然后发现,咦,原来是有循环节的!
    然后就随随便便的搞定了……

    然后再说一个正经一些的做法:
    首先对于一个数xD(x)x*D(x),我们可以将其表示为(9t+D(x))D(x)(9t+D(x))*D(x)
    D(x)D(x)的取值是很少的,也就只有99种。
    我们把它当成常数来看,然后就变成9D(x)t+D2(x)9D(x)*t+D^2(x),变成at+bat+b的形式。
    对于一个D(x)D(x),我们可以很容易地计算出它在某一个区间里的贡献。
    然后我们要去重。
    如何去重?容斥原理,将一些式子合并一下就可以了。用扩展中国剩余定理就好。
    可以手打扩展中国剩余定理,其实也是可以推出来的嘛……
    可是某些机智懒惰的同学发现了一个好方法:
    我们将所有的D(x)D(x)的式子列出来,然后将它们都模99
    然后就会惊奇地发现下面的这张表:
    1 4 0 7 7 0 4 1 0
    只有模数相同的有可能可以合并。
    所以运算量大大减少……
    然后我就全部手推出来了。具体见程序(有的式子合并之后无解,我也有注释)。
    然后这题就愉快地解决了。


    代码

    using namespace std;
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    struct func{
    	int a,b,ty;
    } d[20];
    int cnt;
    inline long long getans(long long lim){
    	long long res=0;
    	for (int i=1;i<=cnt;++i)
    		if (lim-d[i].b>=0)
    			res+=((lim-d[i].b)/d[i].a+1)*d[i].ty;//计算贡献……不用解释
    	return res;
    }
    int main(){
    	for (int i=1;i<=9;++i)
    		d[++cnt]={i*9,i*i,1};
    	d[++cnt]={72,64,-1};//d[1] and d[8]
    	d[++cnt]={126,112,-1};//d[2] and d[7]
    	d[++cnt]={180,160,-1};//d[4] and d[5]
    	d[++cnt]={54,36,-1};//d[3] and d[6] 其实在仔细观察之后可以发现,这个和d[6]抵消了。
    	//d[3] and d[9]=empty
    	//d[6] and d[9]=empty
    	//d[3] and d[6] and d[9]=empty
    	int T;
    	scanf("%d",&T);
    	while (T--){
    		long long l,r;
    		scanf("%lld%lld",&l,&r);
    		printf("%lld
    ",getans(r)-getans(l-1));
    	}
    	return 0;
    }
    

    总结

    每次做比赛时,我要么是不屑于打表,要么就是懒得打表。
    可是经验和事实告诉我们,打表是信息学竞赛选手必备的技能!
    我们要培养起自己的打表精神,让它贯彻入信息学竞赛中!
    瞎BB结束

  • 相关阅读:
    BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )
    BZOJ 2134: 单选错位( 期望 )
    BZOJ 1030: [JSOI2007]文本生成器( AC自动机 + dp )
    BZOJ 2599: [IOI2011]Race( 点分治 )
    BZOJ 3238: [Ahoi2013]差异( 后缀数组 + 单调栈 )
    ZOJ3732 Graph Reconstruction Havel-Hakimi定理
    HDU5653 Bomber Man wants to bomb an Array 简单DP
    HDU 5651 xiaoxin juju needs help 水题一发
    HDU 5652 India and China Origins 并查集
    HDU4725 The Shortest Path in Nya Graph dij
  • 原文地址:https://www.cnblogs.com/jz-597/p/11145249.html
Copyright © 2011-2022 走看看