HDU 5869 Different GCD Subarray Query(离线+gcd)

gcd
线gcd
gcdlogai
mapgcd
gcdgcd
i
gcd1+1


代码

#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")

using namespace std;
#define   MAX           100005
#define   MAXN          1000005
#define   maxnode       105
#define   sigma_size    2
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   lrt           rt<<1
#define   rrt           rt<<1|1
#define   middle        int m=(r+l)>>1
#define   LL            long long
#define   ull           unsigned long long
#define   mem(x,v)      memset(x,v,sizeof(x))
#define   lowbit(x)     (x&-x)
#define   pii           pair<int,LL>
#define   bits(a)       __builtin_popcount(a)
#define   mk            make_pair
#define   limit         10000

//const int    prime = 999983;
const int    INF   = 0x3f3f3f3f;
const LL     INFF  = 0x3f3f;
//const double pi    = acos(-1.0);
const double inf   = 1e18;
const double eps   = 1e-9;
const LL     mod   = 1e9+7;
const ull    mx    = 133333331;

/*****************************************************/
inline void RI(int &x) {
      char c;
      while((c=getchar())<'0' || c>'9');
      x=c-'0';
      while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0';
 }
/*****************************************************/

map<int,int> d[2],ma;
int a[MAX];
int sum[MAX<<2];
int ans[MAX];
struct Node{
    int l,r,id;
    bool operator <(const Node&e) const{
        return r<e.r;
    }
}p[MAX];

int pushup(int rt){
    sum[rt]=sum[lrt]+sum[rrt];
}

void build(int l,int r,int rt){
    sum[rt]=0;
    if(l==r) return;
    middle;
    build(lson);
    build(rson);
}

void update(int l,int r,int rt,int pos,int d){
    if(l==r){
        sum[rt]+=d;
        return;
    }
    middle;
    if(pos<=m) update(lson,pos,d);
    else update(rson,pos,d);
    pushup(rt);
}

int query(int l,int r,int rt,int L,int R){
    if(L<=l&&r<=R) return sum[rt];
    middle;
    int ans=0;
    if(L<=m) ans+=query(lson,L,R);
    if(R>m) ans+=query(rson,L,R);
    return ans;
}

int main(){
    int n,m;
    while(cin>>n>>m){
        d[0].clear();
        d[1].clear();ma.clear();
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=0;i<m;i++){
            scanf("%d%d",&p[i].l,&p[i].r);
            p[i].id=i;
        }
        sort(p,p+m);
        build(1,n,1);
        int cnt=0,tmp=1;
        int tot=0;
        for(int i=1;i<=n;i++){
            for(map<int,int>::iterator it=d[cnt].begin();it!=d[cnt].end();it++){
                int x=__gcd(a[i],it->first);
                d[tmp][x]=max(d[tmp][x],it->second);
            }
            d[tmp][a[i]]=max(d[tmp][a[i]],i);
            for(map<int,int>::iterator iit=d[tmp].begin();iit!=d[tmp].end();iit++){
                int x=iit->first;
                if(ma.count(x)&&ma[x]<d[tmp][x]){
                    update(1,n,1,ma[x],-1);
                    update(1,n,1,d[tmp][x],1);
                } 
                else if(!ma.count(x)) update(1,n,1,d[tmp][x],1);
                ma[x]=d[tmp][x];
            }
            d[cnt].clear();
            swap(cnt,tmp);
            while(tot<m&&p[tot].r<=i){
                ans[p[tot].id]=query(1,n,1,p[tot].l,p[tot].r);
                tot++;
            }
        }
        for(int i=0;i<m;i++){
            printf("%d\n",ans[i]);
        }
    }
    return 0;
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值