zoukankan      html  css  js  c++  java
  • 计蒜客 41391.query-二维偏序+树状数组(预处理出来满足情况的gcd) (The Preliminary Contest for ICPC Asia Xuzhou 2019 I.) 2019年徐州网络赛)

    query

    Given a permutation pp of length nn, you are asked to answer mm queries, each query can be represented as a pair (l ,r )(l,r), you need to find the number of pair(i ,j)(i,j) such that l le i < j le rli<jr and min(p_i,p_j) = gcd(p_i,p_j )min(pi,pj)=gcd(pi,pj).

    Input

    There is two integers n(1 le n le 10^5)n(1n105), m(1 le m le 10^5)m(1m105) in the first line, denoting the length of pp and the number of queries.

    In the second line, there is a permutation of length nn, denoting the given permutation pp. It is guaranteed that pp is a permutation of length nn.

    For the next mm lines, each line contains two integer l_ili and r_i(1 le l_i le r_i le n)ri(1lirin), denoting each query.

    Output

    For each query, print a single line containing only one integer which denotes the number of pair(i,j)(i,j).

    样例输入

    3 2
    1 2 3
    1 3
    2 3

    样例输出

    2
    0

    题意很好理解。就是二维偏序+树状数组。

    比赛时的队友们的代码写的太丑,学了一下别人的代码,写的很好。

    参考链接:query(2019徐州网络赛)(一点思维+树状数组)

    代码:

     1 //I.二维偏序+树状数组
     2 //提前预处理出来所有的倍数关系,然后按顺序,先插入然后查询
     3 #include<bits/stdc++.h>
     4 using namespace std;
     5 typedef long long ll;
     6 #define pb push_back
     7 #define mp make_pair
     8 #define pii pair<int,int>
     9 const int maxn=1e5+10;
    10 
    11 int a[maxn],pos[maxn],tree[maxn],ans[maxn];
    12 int n,m;
    13 vector<int> gcd[maxn];
    14 vector<pii> op[maxn];
    15 
    16 int lowbit(int x)
    17 {
    18     return x&(-x);
    19 }
    20 
    21 void add(int x,int val)
    22 {
    23     for(int i=x;i<=n;i+=lowbit(i)){
    24         tree[i]+=val;
    25     }
    26 }
    27 
    28 int query(int n)
    29 {
    30     int ans=0;
    31     for(int i=n;i>0;i-=lowbit(i)){
    32         ans+=tree[i];
    33     }
    34     return ans;
    35 }
    36 
    37 int main()
    38 {
    39     scanf("%d%d",&n,&m);
    40     for(int i=1;i<=n;i++){
    41         scanf("%d",&a[i]);
    42         pos[a[i]]=i;//记录下标
    43     }
    44     for(int i=1;i<=n;i++){
    45         for(int j=a[i]*2;j<=n;j+=a[i]){
    46             gcd[max(i,pos[j])].pb(min(i,pos[j]));//预处理
    47         }
    48     }
    49     for(int i=1;i<=m;i++){
    50         int l,r;
    51         scanf("%d%d",&l,&r);
    52         op[r].pb(mp(l,i));//保存查询
    53     }
    54     for(int i=1;i<=n;i++){
    55         for(auto it:gcd[i]){
    56             add(it,1);//先把插入
    57         }
    58         for(auto it:op[i]){
    59             ans[it.second]=query(i)-query(it.first-1);//查询
    60         }
    61     }
    62     for(int i=1;i<=m;i++){
    63         printf("%d
    ",ans[i]);
    64     }
    65     return 0;
    66 }
  • 相关阅读:
    资源放送丨《Oracle存储过程中的性能瓶颈点》PPT&视频
    警示:一个update语句引起大量gc等待和业务卡顿
    周末直播丨细致入微
    Java VS Python:哪个未来发展更好?
    【LeetCode】279.完全平方数(四种方法,不怕不会!开拓思维)
    事件驱动
    Android初级教程以动画的形式弹出窗体
    Android简易实战教程--第五话《开发一键锁屏应用》
    迎战大数据-Oracle篇
    Android初级教程获取手机位置信息GPS与动态获取最佳方式
  • 原文地址:https://www.cnblogs.com/ZERO-/p/11488127.html
Copyright © 2011-2022 走看看