zoukankan      html  css  js  c++  java
  • 牛客小白月赛39 G. 冷静(树状数组/线性筛)

    链接:https://ac.nowcoder.com/acm/contest/11216/G
    来源:牛客网

    题目描述

    想去实现宏大的梦想 向着那遥不可及的地方

    想在那一片纯白的世界 留下我最初的脚印

    在世界的终端 太阳在永不停息地运转

    南风终将吹过小岛 轻抚我的柔发

    想去实现心底小小的梦

    ——《ハルカトオク》

    痛定思痛,奋楫争先再出发……

    q 次询问。每次询问给定 n 和 K,问 1 ~ n 中有多少数可以表示为大于等于 K 的质数的乘积(一个数可以乘多次)。

    输入描述:

    第一行读入一个整数q 
    接下来q行每行读入2个整数,第i行表示 niniKiKi
    1≤q≤3e61≤q≤3e6,1≤ni,Ki≤3e61≤ni,Ki≤3e6。
    

    输出描述:

    q行,共 q 个数,分别表示 q 次询问的答案。
    

    示例1

    输入

    复制

    1
    100 5
    

    输出

    复制

    32
    

    示例2

    输入

    复制

    2
    20 3
    10 5
    

    输出

    复制

    9
    2
    

    暴力做法就是把每个数唯一分解掉,每个查询暴力统计。考虑如何优化。首先,1到n每个数的最小质因子可以通过线性筛(O(n))地求出来,但是这样对于每次查询的复杂度也是(O(n))的,需要继续优化。因为整体值域比较小,可以借助树状数组维护,离线处理询问。具体来说,首先读入所有的询问并按照n从小到大进行排序并处理,然后维护一个变量num,每处理到一个询问,当num小于这个询问的k值的时候就不断把num这个数的最小质因子插入树状数组维护的桶然后把num++。最后(O(log(n)))查询答案并更新到答案数组。

    注意这个题卡了一波cout

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    int prime[10000005], primesize, phi[10000005], mn[10000005];
    bool isprime[10000005];
    int read() {
        int s=0,w=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
        return s*w;
    }
    void getlist(int listsize) {
        for(int i = 1; i <= 3000002; i++) isprime[i] = 1, mn[i] = 0x3f3f3f3f;
        isprime[1] = false;
        for(int i = 2; i <= listsize; i++) {
            if(isprime[i]) prime[++primesize] = i, mn[i] = i;
             for(int j = 1; j <= primesize && i * prime[j] <= listsize; j++) {
                isprime[i * prime[j]] = false;
                mn[i * prime[j]] = min(mn[i * prime[j]], prime[j]);
                if(i % prime[j] == 0) break;
            }
        }
    }
    struct ask {
    	int n, k, id;
    	bool operator < (const ask& o) const {
    		return n < o.n;
    	}
    };
    int ans[3000005];
    int b[3000005];
    void modify(int x, int y) {
    	for(; x <= 3000000; x += (x & -x)) {
    		b[x] += y;
    	}
    }
    int query(int x) {
    	int ans = 0;
    	for(; x; x -= (x & -x)) {
    		ans += b[x];
    	}
    	return ans;
    }
    int main() {
    
    	getlist(3000000);
    	int q;
    	cin >> q;
    	vector<ask> v;
    	for(int i = 1; i <= q; i++) {
    		int n, k;
    		n = read(), k = read();
    		ask tmp = {n, k, i};
    		v.push_back(tmp);
    	}
    	sort(v.begin(), v.end());
    	int num = 2;
    	for(auto a : v) {
    		while(num <= a.n) {
    			modify(mn[num], 1);
    			num++;
    		}
    		ans[a.id] = query(a.n) - query(a.k - 1);
    	}
    	for(int i = 1; i <= q; i++) {
    		printf("%d
    ", ans[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    P4178 Tree
    CF437D The Child and Zoo
    CF1032G Chattering ST表+倍增
    P4165 [SCOI2007]组队 推柿子+差分
    P1450 [HAOI2008]硬币购物 容斥原理+完全背包
    P6275 [USACO20OPEN]Sprinklers 2: Return of the Alfalfa P 轮廓线DP
    P6009 [USACO20JAN]Non-Decreasing Subsequences P 矩阵优化DP
    P2605 [ZJOI2010]基站选址 线段树优化DP
    P5597 【XR-4】复读 思维题 +二叉树合并
    P5304 [GXOI/GZOI2019]旅行者 最短路+位运算优化
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/15448941.html
Copyright © 2011-2022 走看看