【2019徐州网络赛 I】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≤i a n d   min ⁡ ( p i , p j ) = gcd ⁡ ( p i , p j ) and\ \min(p_i,p_j) = \gcd(p_i,p_j ) and min(pi,pj)=gcd(pi,pj)
Input
There is two integers n(1 \le n \le 10^5)), m(1 \le m \le 10^5)in the first line, denoting the length of p and the number of queries.

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

For the next mm lines, each line contains two integer l_i and r_i(1 <= l_i <=r_i <=n)denoting each query.

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

样例输入
3 2
1 2 3
1 3
2 3
样例输出
2
0

二维偏序
代码:

#include
#include
#include
#include
#include
#define maxx 1000005
#define N 26
using namespace std;
typedef long long ll;
struct node
{
    int l,r;
    int id;
}q[100005];
int ans[100005];
bool cmp1(node x1,node x2)
{
    return x1.r<x2.r;
}
struct node2
{
    int l,r;
    node2(int l,int r):l(l),r(r){}
};
bool cmp2(node2 x1,node2 x2)
{
    return x1.r<x2.r;
}
int a[100005];
vector<node2> b;
int n,m;
int c[maxx];
int total;
inline void add(int x)
{
    for(;x<=n;x+=x&-x)c[x]++;
}
inline int ask(int x)
{
    int ans=0;
    for(;x;x-=x&-x)ans+=c[x];
    return ans;
}

int main()
{
    cin>>n>>m;
    int x;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        a[x]=i;
    }
    for(int i=1;i<=n;i++)
        for(int j=i+i;j<=n;j+=i)
        {
            int l=a[i],r=a[j];
            if(l>r)swap(l,r);
            b.push_back(node2(l,r));
        }
    sort(b.begin(),b.end(),cmp2);
    total=b.size();
    //for(int i=0;i
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&q[i].l,&q[i].r);
        q[i].id=i;
    }
    sort(q+1,q+1+m,cmp1);
    int now=0;

    for(int i=1;i<=m;i++)
    {
        while(now<total&&b[now].r<=q[i].r)
        {
            add(b[now].l);now++;
        }
        ans[q[i].id]=ask(q[i].r)-ask(q[i].l-1);
        //cout<
    }
    for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
    return 0;
}

你可能感兴趣的:(二维偏序)