我是靠谱客的博主 甜甜含羞草,最近开发中收集的这篇文章主要介绍Gym - 101102J J. Divisible Numbers 位运算+优化+前缀和,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

J. Divisible Numbers
time limit per test
3.5 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given an array A of integers of size N, and Q queries. For each query, you will be given a set of distinct integers S and two integers L and R that represent a range in the array. Your task is to count how many numbers in the given range are divisible by at least one number from the set.

Input

The first line of input contains a single integer T, the number of test cases.

The first line of each test case contains two integers, N and Q (1 ≤ N, Q ≤ 105), the size of the array and the number of queries, respectively.

The next line contains N space-separated integers, the values of the array A (1 ≤ Ai ≤ 109).

Each of the next Q lines contain the description of one query in the form:

LRS

Where L and R (1 ≤ L ≤ R ≤ N) represent the range, and S is an integer between 1 and 1023 (inclusive) and represents the set; consider the binary representation of the number S, if the ith bit (1-based) is 1, then the number i belongs to the set. Since S is less than1024, the values in the set are between 1 and 10.

For example: if S is equal to 6, the binary representation of 6 is 110, and this means the values in the set are 2 and 3.

The input was given in this way to reduce the size of the input file.

Output

Print the answer for each query on a single line.

Example
input
1
4 2
2 5 3 8
1 3 2
2 4 355
output
1
3



Source

2016 ACM Amman Collegiate Programming Contest

UESTC 2017 Winter Training #1

Gym - 101102J


My Solution

题意:给出n个数,然后每次询问l r s,表示在lr区间内有多少个x,是x能被集合s里的至少一个元素整除,s表示一个{1~10}的子集


位运算+优化+前缀和

可以预处理出前缀和 sum[i][j]表示1~j中能被集合i满足的数的个数,

且i为奇数时比有元素1,lr区间内所有的数必定可以被1整除,所以只剩下512中情况

故 int sum[512][maxn];

读入的时候每次判断v可以被哪些数整除,然后得到集合s,s说表示的集合中所有的元素皆可以整除v,

然后用这个s和0~512位于返回非0值则有公共元素,则sum[j][i] = sum[j][i-1] + 1,否则只是普通传递 sum[j][i] = sum[j][i-1];

对于l r s

当s为偶数时 ans = sum[s>>1][r] - sum[s>>][l-1]; s为奇数时 ans = r - l + 1;

复杂度 O(n*512)


#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
typedef long long LL;
const int maxn = 1e5 + 8;

template <class T>
inline void cinn(T &ret)
{
    char c = getchar();
    while(c < '0' || c > '9')
        c = getchar();
    ret = c - '0';
    while(c = getchar(), c>='0' && c<='9')
        ret = ret * 10 + (c - '0');
}

inline void coutt(int a)
{    //  输出外挂
    if (a < 0)
    {
        putchar('-');
        a = -a;
    }
    if (a >= 10)
    {
       coutt(a / 10);
    }
    putchar(a % 10 + '0');
}

int sum[512][maxn];

int main()
{
    #ifdef LOCAL
    freopen("g.txt", "r", stdin);
    //freopen("g.coutt", "w", stdcoutt);

    #endif // LOCAL
    ios::sync_with_stdio(false); cin.tie(0);

    int T, n, q, v, i, j, l, r, s;
    cinn(T);
    while(T--){
        cinn(n); cinn(q);
        for(i = 1; i <= n; i++){
            cinn(v);
            s = 0;
            for(j = 2; j <= 10; j++){
                if(v % j == 0) s |= 1<<(j - 2);

            }
            //ccoutt << s << endl;
            for(j = 0; j < 512; j++){
                sum[j][i] = sum[j][i - 1];
                if(j & s) sum[j][i] += 1;
            }
        }
        while(q--){
            cinn(l); cinn(r); cinn(s);
            if(s&1) coutt(r - l + 1);
            else coutt(sum[s>>1][r] - sum[s>>1][l - 1]);
            puts("");
        }

    }
    return 0;
}



  Thank you!

                                                                                                                                               ------from ProLights

最后

以上就是甜甜含羞草为你收集整理的Gym - 101102J J. Divisible Numbers 位运算+优化+前缀和的全部内容,希望文章能够帮你解决Gym - 101102J J. Divisible Numbers 位运算+优化+前缀和所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部