zoukankan      html  css  js  c++  java
  • Maximum number, GCD condition (codechef March Challenge 2014)

    题目 : http://acm.bnu.edu.cn/v3/problem_show.php?pid=40489

    最近做到的一道蛮有意思的题目(codechef现在的题目确实很赞了)

    题意 :中文题面 (cc的一大好处就是有中文翻译,嘿嘿)

    区间Max = max{a_i|gcd(a_i, g) > 1 && x <= i <= y}

    做法 : 一开始我是用分块做的,复杂的O(m * sqrt(n) * C) C 是所含不同素数的个数, C大概最大只有6或7吧

    然后裸裸的T了,换了一个姿势:用线段树或者RMQ把查询从sqrt(n) -> log(n), 这里最初的想法就是直接对于每个素数开一个线段树,但是这样预处理空间和时间都过不了

    ,但是考虑的其实n个数都分解一下只有C*n个数,那么的话我们可以用动态开线段树的方法,当然这个我不会- - !,还有一种比较好的实现方式是对于每个素数都建立一段段的RMQ,额,, 具体就是比如 a[] : 2, 3, 4, 6 那么我建立一个RMQ为 :2 4 6 3 6,前三个是2的倍数,后两个是3的倍数,,并通过一些其他辅助操作可以使得复杂度降为log(n)。

    分块做法(TLE) :

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <vector>
     5 
     6 using namespace std;
     7 inline int gcd(int a, int b) {return !b ? a : gcd(b, a % b);}
     8 const int MAXN = 100005;
     9 int check[MAXN] = {0};
    10 const int M = 320;
    11 vector<int> prime[MAXN];
    12 int ptot = 0;
    13 int n, m;
    14 int blocks[1<<9][10005];
    15 int a[MAXN];
    16 void init(int N) {
    17     for (int i = 2; i <= N; i++) {
    18         if (!check[i]) {
    19             for (int j = 1; j * i <= N; j++) {
    20                 prime[j * i].push_back(i);
    21                 check[i * j] = 1;
    22             }
    23             check[i] = ++ ptot;
    24         }
    25     }
    26 }
    27 vector<int> G[MAXN];
    28 int query(int x, int y, int e) {
    29     return upper_bound(G[e].begin(), G[e].end(), y) - lower_bound(G[e].begin(), G[e].end(), x);
    30 }
    31 
    32 int main() {
    33     init(100000);
    34     scanf("%d%d", &n, &m);
    35     for (int i = 1; i <= n; i++) {
    36         scanf("%d", &a[i]);
    37         int e = i / M;
    38         for (int j = 0; j < prime[a[i]].size(); j++) {
    39             int v = prime[a[i]][j];
    40             blocks[e][check[v]] = max(blocks[e][check[v]], a[i]);
    41         }
    42         G[a[i]].push_back(i);
    43     }
    44     while (m --) {
    45         int g, x, y;
    46         scanf("%d%d%d", &g, &x, &y);
    47         int l = x / M, r = y / M, Max = -1;
    48         if (l == r) {
    49             for (int i = x; i <= y; i++) {
    50                 if (gcd(g, a[i]) > 1) Max = max(Max, a[i]);
    51             }
    52         }else {
    53             for (int i = x; i < (l+1) * M; i++) {
    54                 if (gcd(g, a[i]) > 1) Max = max(Max, a[i]);
    55             }
    56             for (int i = r * M; i <= y; i++) {
    57                 if (gcd(g, a[i]) > 1) Max = max(Max, a[i]);
    58             }
    59             for (int i = 0; i < prime[g].size(); i++) {
    60                 int v = prime[g][i];
    61                 for (int j = l + 1; j <= r - 1; j++) {
    62                     if (blocks[j][v] > 0)Max = max(Max, blocks[j][v]);
    63                 }
    64             }
    65         }
    66         if (Max == -1) printf("-1 -1
    ");
    67         else {
    68             printf("%d %d
    ", Max, query(x, y, Max));
    69         }
    70     }
    71     return 0;
    72 }
    View Code

    RMQ做法:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <vector>
     5 
     6 using namespace std;
     7 const int MAXN = 100005;
     8 struct RMQ {
     9     int a[MAXN * 7][20];
    10     int log2[MAXN * 7];
    11     void init(int A[], int N) {
    12         for (int i = 0; i < MAXN * 7; i++) log2[i] = (i == 0 ? -1 : log2[i >> 1] + 1);
    13         for (int i = 1; i <= N; i++) a[i][0] = A[i];
    14         for (int j = 1; (1 << j) <= N; j++) {
    15             for (int i = 1; i + (1<<j) - 1 <= N; i++) {
    16                 a[i][j] = max(a[i][j-1], a[i + (1<<(j-1))][j - 1]);
    17             }
    18         }
    19     }
    20     int rmq(int L, int R) {
    21         if (R < L) return 0;
    22         int k = log2[R - L + 1];
    23         return max(a[L][k], a[R-(1<<k)+1][k]);
    24     }
    25 }AC;
    26 vector<int> prime[MAXN];
    27 int check[MAXN] = {0}, ptot = 0;
    28 void init(int N) {
    29     for (int i = 2; i <= N; i++) {
    30         if (!check[i]) {
    31             for (int j = 1; j * i <= N; j++) {
    32                 prime[j * i].push_back(i);
    33                 check[i * j] = 1;
    34             }
    35             check[i] = ++ ptot;
    36         }
    37     }
    38 }
    39 vector<int> G[MAXN];
    40 int query(int x, int y, int e) {
    41     return upper_bound(G[e].begin(), G[e].end(), y) - lower_bound(G[e].begin(), G[e].end(), x);
    42 }
    43 int n, m;
    44 int b[MAXN * 7];
    45 int a[MAXN];
    46 int pre[MAXN];
    47 vector<int> gao[MAXN];
    48 
    49 int main() {
    50     init(100000);
    51     scanf("%d%d", &n, &m);
    52     for (int i = 1; i <= n; i++) {
    53         scanf("%d", &a[i]);
    54         for (int j = 0; j < prime[a[i]].size(); j++) {
    55             int v = check[prime[a[i]][j]];
    56             gao[v].push_back(i);
    57         }
    58         G[a[i]].push_back(i);
    59     }
    60     int tot = 0;
    61     for (int i = 1; i <= ptot; i++) {
    62         if (gao[i].size() == 0) continue;
    63         pre[i] = tot;
    64         for (int j = 0; j < gao[i].size(); j++) {
    65             b[++ tot] = a[gao[i][j]];
    66         }
    67     }
    68     AC.init(b, tot);
    69     while (m--) {
    70         int g, x, y, Max = -1;
    71         scanf("%d%d%d", &g, &x, &y);
    72         for (int i = 0; i < prime[g].size(); i++) {
    73             int v = check[prime[g][i]];
    74             int r = upper_bound(gao[v].begin(), gao[v].end(), y) - gao[v].begin() + pre[v] + 1;
    75             int l = lower_bound(gao[v].begin(), gao[v].end(), x) - gao[v].begin() + pre[v] + 1;
    76             r --;
    77             if (r >= l)Max = max(Max, AC.rmq(l, r));
    78         }
    79         if (Max == -1) {
    80             printf("-1 -1
    ");
    81         }else {
    82             printf("%d %d
    ", Max, query(x, y, Max));
    83         }
    84     }
    85     return 0;
    86 }
    View Code
  • 相关阅读:
    常见试题
    Makefile学习笔记
    安装java
    IntelliJ IDEA for mac 快捷键
    JPA--Caused by: javax.persistence.PersistenceException: [PersistenceUnit: mysqlJPA] Unable to configure EntityManagerFactory
    log4j 配置
    Numbers
    mac 命令
    Intellij IDEA for mac 快捷键
    vim命令
  • 原文地址:https://www.cnblogs.com/danceonly/p/4029818.html
Copyright © 2011-2022 走看看