2013年 ACMICPC 杭州赛区H题

思路:树状数组统计。待验证,不知道是否对。 

#include<cstdio>

#include<cstring>

#include<cmath>

#include<iostream>

#include<algorithm>

#define lowbit(x) (x&(-x))

#define Maxn 200010

using namespace std;

int C[Maxn],vi[Maxn],pre[Maxn],n,num[Maxn],ans[Maxn],ov[Maxn];

struct Qu{

    int l,r,i;

}q[Maxn];

int cmp(Qu a,Qu b)

{

    return a.r<b.r;

}

void update(int pos,int val)

{

    while(pos){

        C[pos]+=val;

        pos-=lowbit(pos);

    }

}

int sum(int pos)

{

    int s=0;

    while(pos<=n){

        s+=C[pos];

        pos+=lowbit(pos);

    }

    return s;

}

int main()

{

    int m,i,j;

    while(scanf("%d%d",&n,&m),n||m){

        memset(C,0,sizeof(C));

        memset(vi,0,sizeof(vi));

        memset(pre,0,sizeof(pre));

        memset(ov,0,sizeof(ov));

        for(i=1;i<=n;i++)

            scanf("%d",num+i);

        for(i=1;i<=m;i++){

            scanf("%d%d",&q[i].l,&q[i].r);

            q[i].i=i;

        }

        sort(q+1,q+1+m,cmp);

        int r=1,temp,pos;

        for(i=1;i<=n;i++){

            update(i,1);

            pos=0;

            for(j=2;j*j<=num[i];j++){

                if(num[i]%j) continue;

                if(!vi[pre[j]]&&pre[j]) {

                    update(pre[j],-1);

                    if(ov[pre[j]])

                        update(ov[pre[j]],1);

                    vi[pre[j]]=1;

                }

                pos=max(pos,pre[j]);

                pre[j]=i;

                if(j*j==num[i]) continue;

                temp=num[i]/j;

                if(!vi[pre[temp]]&&pre[temp]){

                    update(pre[temp],-1);

                    if(ov[pre[temp]])

                        update(ov[pre[temp]],1);

                    vi[pre[temp]]=1;

                }

                pos=max(pos,pre[temp]);

                pre[temp]=i;

            }

            if(!vi[pre[num[i]]]&&pre[num[i]]){

                update(pre[num[i]],-1);

                if(ov[pre[num[i]]])

                        update(ov[pre[num[i]]],1);

                vi[pre[num[i]]]=1;

            }

            pos=max(pos,pre[num[i]]);

            pre[num[i]]=i;

            if(pos){

                update(pos,-1);

                ov[i]=pos;

            }

            while(r<=m&&q[r].r==i){

                ans[q[r].i]=sum(q[r].l);

                r++;

            }

        }

        for(i=1;i<=m;i++)

            printf("%d\n",ans[i]);

    }

    return 0;

}

 

你可能感兴趣的:(ICPC)