题意:给你一个长度为n 的数组,q次询问,每次询问给一个区间 l,r 问原数组有多少个连续的区间的GCD与该区间的GCD 相等。
思路:用MAP记录所有区间的各种GCD值的数量。
代码如下:(不要全部用LL,要T呀)
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<vector>
#include<iostream>
#include<string>
#include<set>
#include<map>
#include<algorithm>
#include<complex>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define nn 100100
#define maxk 18
#define LL long long
#define Uint unsiged long long
#define mod 1000000007
#define inf 0xffffff
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
struct FastIO {
static const int S = 1310720;
int wpos; char wbuf[S];
FastIO() : wpos(0) {}
inline int xchar() {
static char buf[S];
static int len = 0, pos = 0;
if (pos == len)
pos = 0, len = fread(buf, 1, S, stdin);
if (pos == len) return -1;
return buf[pos ++];
}
inline int xuint() {
int c = xchar(), x = 0;
while (c <= 32) c = xchar();
for (;'0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
return x;
}
inline int xint() {
int s = 1, c = xchar(), x = 0;
while (c <= 32) c = xchar();
if (c == '-') s = -1, c = xchar();
for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
return x * s;
}
inline void xstring(char *s) {
int c = xchar();
while (c <= 32) c = xchar();
for(; c > 32; c = xchar()) *s++ = c;
*s = 0;
}
inline void wchar(int x) {
if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0;
wbuf[wpos ++] = x;
}
inline void wint(int x) {
if (x < 0) wchar('-'), x = -x;
char s[24];
int n = 0;
while (x || !n) s[n ++] = '0' + x % 10, x /= 10;
while (n--) wchar(s[n]);
}
inline void wstring(const char *s) {
while (*s) wchar(*s++);
}
~FastIO() {
if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;
}
}io;
int a[nn],n;
int tg[nn<<2];
int get_gcd(int x,int y)
{
return y==0?x:get_gcd(y,x%y);
}
inline void pushup(int rt)
{
tg[rt]=get_gcd(tg[rt<<1],tg[rt<<1|1]);
}
void build(int l,int r,int rt)
{
if(l==r)
{
tg[rt]=a[l];
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
int query(int l,int r,int rt,int ll,int rr)
{
if(ll<=l && r<=rr)
return tg[rt];
int mid=(l+r)>>1;
if(rr<=mid) return query(lson,ll,rr);
else if(ll>mid) return query(rson,ll,rr);
else return get_gcd(query(lson,ll,rr),query(rson,ll,rr));
}
int main()
{
int m,t;
t=io.xint();
for(int tt=1;tt<=t;tt++)
{
n=io.xint();
for(int i=1;i<=n;i++)
a[i]=io.xint();
map<int,LL>mp;
build(1,n,1);
for(int i=1;i<=n;i++)
{
int val=a[i];
int sl=i,sr=n,l=i,r=n;
while(val>=1)
{
l=sl;r=sr;
if(val==1)
{
mp[1]+=(LL)(n-l+1);
break;
}
while(l<r)
{
int mid=(l+r)>>1;
int tmp=query(1,n,1,i,mid);
if(tmp<val) r=mid-1;
else
{
l=mid;
if(l+1==r)
{
int val1=query(1,n,1,i,l);
int val2=query(1,n,1,i,r);
if(val1==val2) l=r;
break;
}
}
}
mp[val]+=(LL)(l-sl+1);
sl=l+1;
sr=n;
if(sl<=n) val=query(1,n,1,i,sl);
else break;
}
}
printf("Case #%d:\n",tt);
m=io.xint();
while(m--)
{
int x,y;
x=io.xint();
y=io.xint();
int ans=query(1,n,1,x,y);
printf("%d %lld\n",ans,mp[ans]);
}
}
return 0;
}