zoukankan      html  css  js  c++  java
  • Codeforces Gym 101775D Mr. Panda and Geometric Sequence(2017-2018 ACM-ICPC Asia East Continent League Final,D题,枚举剪枝)

    题目链接  ECL-Final 2017 Problem D

    题意  给定$2*10^{5}$组询问,每个询问求$l$到$r$之间有多少个符合条件的数

    如果一个数小于等于$10^{15}$, 并且能被分割成一个至少有$3$项的递增等比数列(公比可以不为整数)

    那么这个数是符合条件的。

    比赛的时候我大概觉得这应该不是数位DP,是一个比较trick的枚举题。

    但是我总感觉哪个地方不太对,或者说是没有写这道题的意识,一直瘫在那里。

    今天AC了这个题之后真的后悔莫及,但是一点用都没有。

     

    从至少有$3$项这个条件入手。

    假设数列只有$3$项。

    因为数列递增,所以第二项一定不超过$10^{5}$,

    所以等比数列的公比

    $frac{q}{p} <= frac{a_{2}}{a_{1}} <= a_{2} <= 10^{5}$

    设第一项为$kp^{2}$, 第二项为$kpq$, 第三项为$kq^{2}$

    那么$kpq <= 10^{5}$,即$pq <= 10^{5}$;

    枚举符合条件的$p$和$q$,发现枚举量不超过$4*10^{5}$;

    在这个基础上枚举$k$,然后求出整个数列,并考虑那些项数大于$3$的数列,

    最后sort一下二分查找就可以了。

    #include <ctime>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    
    typedef long long LL;
    
    const int N = 1e5 + 10;
    
    LL a[N * 100];
    LL ten[20];
    LL l, r;
    int cnt = 0;
    int T, ca = 0;
    
    int solve(LL x){ return upper_bound(a + 1, a + cnt + 1, x) - a - 1; }
    
    inline int calc(LL x){
    	int ret = 0;
    	for (; x; x /= 10) ++ret;
    	return ret;
    }
    
    LL mer(LL x, LL y){ return x * ten[calc(y)] + y; }
    
    int main(){
    
    	ten[0] = 1ll;
    	rep(i, 1, 18) ten[i] = ten[i - 1] * 10ll;
    
    	rep(p, 1, 1e5){
    		rep(q, p + 1, 1e5){
    			if (1ll * p * q >= 1e5) break;
    			if (__gcd(p, q) > 1) continue;
    
    			rep(k, 1, 1e5 / p / q){
    				LL x = 1ll * k * p * p;
    				LL y = 1ll * k * p * q;
    				LL z = 1ll * k * q * q;
    
    				int cnt_len = calc(x) + calc(y) + calc(z);
    				if (cnt_len > 15) break;
    
    				LL now = mer(mer(x, y), z);
    				a[++cnt] = now;
    
    				while (true){
    					if (calc(z) >= 9) break;
    					if (z * z % y > 0) break;
    					LL nw = z * z / y;
    					int nwlen = calc(nw);
    					if (cnt_len + nwlen > 15) break;
    					cnt_len += nwlen;
    					now = mer(now, nw);
    					a[++cnt] = now;
    					y = z;
    					z = nw;
    				}
    			}
    		}
    	}
    
    	sort(a + 1, a + cnt + 1);
    	scanf("%d", &T);
    	while (T--){
    		scanf("%lld%lld", &l, &r);
    		printf("Case #%d: %d
    ", ++ca, solve(r) - solve(l - 1));
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    在ASP.Net和IIS中删除不必要的HTTP响应头
    Json对象与Json字符串互转
    Jquery ajax传递复杂参数给WebService
    HTTP的KeepAlive是开启还是关闭?
    MQ产品比较-ActiveMQ-RocketMQ
    RocketMQ(7)——通信协议
    mq使用经验
    mq
    RocketMQ
    发送短信验证码实现方案
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/8877625.html
Copyright © 2011-2022 走看看