hdu 5726

  • Post author:
  • Post category:其他


思路:ST表+二分

代码:

#include<cstdio>

#include <cstdlib>

#include <cstring>

#include <algorithm>

#include <map>

typedef long long LL;

using namespace std;

const int maxn = 134536;

int arr[maxn] = {}, book[20][maxn] = {};

int gcd(int xx, int yy)

{


return xx % yy == 0 ? yy : gcd(yy, xx % yy);

}

int query(int ll, int rr)

{


//printf(“query\n”);

//printf(“%d  %d\n”, ll, rr);

int kk = (int)(log2((double)(rr – ll + 1)));

//printf(“%d  %d\n”, kk, rr – (1 << kk) + 1);

return gcd(book[kk][ll], book[kk][rr – (1 << kk) + 1]);

}

void rmq(int n)

{


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

{


book[0][i] = arr[i];

///先记录下这串数字的本身作为公因数

}

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

{


for(int j = 1; j + (1 << i) – 1 <= n;j++)

{


book[i][j] = gcd(book[i – 1][j], book[i – 1][j + (1 << i – 1)]);

///printf(“%d  %d  %d\n”, i, j, book[i][j]);

}

}

}

map<int, long long>maps;

void sets(int n)

{


rmq(n);

maps.clear();

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

{


int j = i, gg = book[0][i];

while(j <= n)

{


int ll = j, rr = n;

while(ll < rr)

{


int mid = (ll + rr + 1) >> 1;

///printf(“lr : %d  %d  %d\n”, ll, rr, mid);

///printf(“%d\n”, query(j, mid));

if(query(j, mid) == gg)

{


ll = mid;

}

else rr = mid – 1;

}

maps[gg] += (ll – j + 1);

//printf(“i  j  ll  gg  maps\n”);

//printf(“%d  %d  %d  %d  %lld\n”, i, j, ll, gg, maps[gg]);

j = ll + 1;

if(j <= n) gg = query(i, j);

}

}

}

int main()

{


int _;

scanf(“%d”, &_);

for(int kcase = 1; kcase <= _; kcase++)

{


printf(“Case #%d:\n”, kcase);

int n, Q, st, ed;

scanf(“%d”, &n);

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

{


scanf(“%d”, &arr[i]);

}

sets(n);

scanf(“%d”, &Q);

for(int i = 0; i < Q; i++)

{


scanf(“%d %d”, &st, &ed);

int gg = query(st, ed);

printf(“%d %lld\n”, gg, maps[gg]);

}

}

return 0;

}

/*

1  1  5  1  5

2  2  4  2  3

2  5  5  7  1

3  3  3  4  1

3  4  5  1  7

4  4  4  6  1

4  5  5  7  2

5  5  5  7  3

*/



版权声明:本文为eletroram原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。