hdu5726 rmq+二分

来源:互联网 发布:网络聊天室 编辑:程序博客网 时间:2024/06/16 23:44

GCD

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3301 Accepted Submission(s): 1189

Problem Description
Give you a sequence of N(N≤100,000) integers : a1,…,an(0

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 1e5 + 10;ll a[maxn];ll dp[maxn][30];int Log[maxn];int n,m;ll gcd(ll x,ll y){    return x == 0?y:gcd(y%x,x);}void initRmq(){    Log[0] = -1;    for(int i = 1; i <= n; i++)    {        Log[i] = (i&(i - 1)) == 0?Log[i - 1] + 1:Log[i - 1];        dp[i][0] = a[i];    }    for(int j = 1; j <= 20; j++)    {        for(int i = 1; i + (1<<j) - 1 <= n; i++)        {            dp[i][j] = gcd(dp[i][j - 1],dp[i + (1<<(j - 1))][j - 1]);        }    }}ll Rmp(int l,int r){    int x = Log[r - l + 1];    return gcd(dp[l][x],dp[r - (1<<x) + 1][x]);}ll bi_search(ll x,int i){    int l = i;    int r = n;    int result = l;    while(l <= r)    {        int mid = (l + r)>>1;        ll term = Rmp(i,mid);        if(term == x)        {            l = mid + 1;            result = mid;        }        else r = mid - 1;;    }    return result;}int main(){    int T;    scanf("%d",&T);    int Case = 1;    while(T--)    {        map<ll,ll> num;        scanf("%d",&n);        for(int i = 1; i <= n; i++)        {            scanf("%I64d",&a[i]);        }        initRmq();        for(int i = 1; i <= n; i++)        {            ll x = a[i];            ll loc = i;            while(loc <= n)            {                ll loc1 = bi_search(x,loc);                //cout<<loc1<<endl;                num[x] += loc1 - loc + 1;                loc1++;                loc = loc1;                x = gcd(x,a[loc]);            }        }        int l,r;        scanf("%d",&m);        printf("Case #%d:\n",Case++);        for(int i = 1; i <= m; i++)        {            scanf("%d%d",&l,&r);            printf("%I64d %I64d\n",Rmp(l,r),num[Rmp(l,r)]);        }    }    return 0;}
1 0
原创粉丝点击