Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <vector>
- #include <utility>
- #define pii pair<int,int>
- #define mp make_pair
- #define nmax 100005
- #define nmaxp 10000005
- #define INF 999999999
- #define MOD 1000000007
- #define lld long long
- using namespace std;
- struct aiNode
- {
- pii mini, maxi;
- long long euv;
- };
- int n, maximum;
- int a[nmax];
- lld v[nmax];
- aiNode ai[4*nmax];
- int l, r;
- vector<int>primes;
- bool prime[nmaxp];
- lld computeAns(lld a, lld b)
- {
- return (a*b)%MOD;
- }
- void build(int node, int l, int r)
- {
- if (l>r) return;
- if (l == r)
- {
- ai[node].euv = v[l], ai[node].maxi = {a[l], l}, ai[node].mini = {a[l], l};
- return;
- }
- int m = (l+r)/2;
- build(node<<1,l,m);
- build(node<<1|1,m+1,r);
- ai[node].maxi = (ai[node<<1].maxi > ai[node<<1|1].maxi ? ai[node<<1].maxi : ai[node<<1|1].maxi);
- ai[node].mini = (ai[node<<1].mini < ai[node<<1|1].mini ? ai[node<<1].mini : ai[node<<1|1].mini);
- ai[node].euv = computeAns(ai[node<<1].euv, ai[node<<1|1].euv);
- }
- pii queryMin(int node, int l, int r, int x, int y)
- {
- if (x<=l && r<=y) return ai[node].mini;
- int m = (l+r)/2;
- pii lans = {INF,-1}, rans = {INF,-1};
- if (x<=m) lans = queryMin(node<<1,l,m,x,y);
- if (y>m) rans = queryMin(node<<1|1,m+1,r,x,y);
- if (lans.first!=INF && rans.first!=INF)
- return (lans.first < rans.first ? lans : rans);
- if (lans.first!=INF)
- return lans;
- return rans;
- }
- pii queryMax(int node, int l, int r, int x, int y)
- {
- if (x<=l && r<=y) return ai[node].maxi;
- int m = (l+r)/2;
- pii lans = {-1,-1}, rans = {-1,-1};
- if (x<=m) lans = queryMax(node<<1,l,m,x,y);
- if (y>m) rans = queryMax(node<<1|1,m+1,r,x,y);
- if (lans.first!=-1 && rans.first!=-1)
- return (lans.first > rans.first ? lans : rans);
- if (lans.first!=-1)
- return lans;
- return rans;
- }
- lld eu(int x)
- {
- lld ret = x;
- for (unsigned i=0;i<primes.size() && primes[i]*primes[i]<=x;++i)
- {
- if (x%primes[i]) continue;
- ret -= (ret/primes[i]);
- while (x%primes[i]==0)
- x/=primes[i];
- }
- if (x>1)
- ret-=(ret/x);
- return ret;
- }
- lld queryAns(int node, int l, int r, int x, int y)
- {
- if (x<=l && r<=y) return ai[node].euv;
- int m = (l+r)/2;
- lld v1=-1, v2=-1;
- if (x<=m)
- v1 = queryAns(node<<1,l,m,x,y);
- if (y>m)
- v2 = queryAns(node<<1|1,m+1,r,x,y);
- if (v1!=-1 && v2!=-1)
- return computeAns(v1, v2);
- if (v1!=-1)
- return v1;
- return v2;
- }
- void erath()
- {
- prime[0] = prime[1] = 1;
- for (int i=2;i<=maximum;++i)
- if (!prime[i])
- {
- primes.push_back(i);
- for (int j=i+i;j<=maximum;j+=i)
- prime[j] = 1;
- }
- }
- int main()
- {
- /*freopen("in","r",stdin);
- freopen("out","w",stdout);*/
- scanf("%d",&n);
- for (int i=1;i<=n;++i)
- {
- scanf("%d",&a[i]);
- if (a[i]>maximum) maximum = a[i];
- }
- erath();
- for (int i=1;i<=n;++i)
- v[i] = eu(a[i]);
- build(1, 1, n);
- int q;
- int ind1, ind2;
- lld v1, v2, v3, v;
- pii gr, ls;
- scanf("%d",&q);
- for (int i=1;i<=q;++i)
- {
- scanf("%d %d",&l,&r);
- v1 = v2 = v3 = v = 1;
- gr = queryMax(1,1,n,l,r);
- ls = queryMin(1,1,n,l,r);
- if (gr.first == ls.first)
- {
- printf("%lld\n", queryAns(1, 1, n, l+2, r));
- continue;
- }
- ind1 = gr.second;
- ind2 = ls.second;
- if (ind1 > ind2) swap(ind1, ind2);
- if (l<ind1)
- v1 = queryAns(1, 1, n, l, ind1-1);
- if (ind2-ind1>=2)
- v2 = queryAns(1, 1, n, ind1+1, ind2-1);
- if (ind2<r)
- v3 = queryAns(1, 1, n, ind2+1, r);
- v = computeAns(v1, v2);
- v = computeAns(v, v3);
- printf("%lld\n", v);
- }
- /*fclose(stdin);
- fclose(stdout);*/
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement