Advertisement
alexOloieri

Untitled

Feb 23rd, 2019
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.91 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <vector>
  3. #include <utility>
  4. #define pii pair<int,int>
  5. #define mp make_pair
  6. #define nmax 100005
  7. #define nmaxp 10000005
  8. #define INF 999999999
  9. #define MOD 1000000007
  10. #define lld long long
  11. using namespace std;
  12. struct aiNode
  13. {
  14.     pii mini, maxi;
  15.     long long euv;
  16. };
  17. int n, maximum;
  18. int a[nmax];
  19. lld v[nmax];
  20. aiNode ai[4*nmax];
  21. int l, r;
  22. vector<int>primes;
  23. bool prime[nmaxp];
  24. lld computeAns(lld a, lld b)
  25. {
  26.     return (a*b)%MOD;
  27. }
  28. void build(int node, int l, int r)
  29. {
  30.     if (l>r) return;
  31.     if (l == r)
  32.     {
  33.         ai[node].euv = v[l], ai[node].maxi = {a[l], l}, ai[node].mini = {a[l], l};
  34.         return;
  35.     }
  36.     int m = (l+r)/2;
  37.     build(node<<1,l,m);
  38.     build(node<<1|1,m+1,r);
  39.     ai[node].maxi = (ai[node<<1].maxi > ai[node<<1|1].maxi ? ai[node<<1].maxi : ai[node<<1|1].maxi);
  40.     ai[node].mini = (ai[node<<1].mini < ai[node<<1|1].mini ? ai[node<<1].mini : ai[node<<1|1].mini);
  41.     ai[node].euv = computeAns(ai[node<<1].euv, ai[node<<1|1].euv);
  42. }
  43. pii queryMin(int node, int l, int r, int x, int y)
  44. {
  45.     if (x<=l && r<=y) return ai[node].mini;
  46.     int m = (l+r)/2;
  47.     pii lans = {INF,-1}, rans = {INF,-1};
  48.     if (x<=m) lans = queryMin(node<<1,l,m,x,y);
  49.     if (y>m) rans = queryMin(node<<1|1,m+1,r,x,y);
  50.     if (lans.first!=INF && rans.first!=INF)
  51.         return (lans.first < rans.first ? lans : rans);
  52.     if (lans.first!=INF)
  53.         return lans;
  54.     return rans;
  55. }
  56. pii queryMax(int node, int l, int r, int x, int y)
  57. {
  58.     if (x<=l && r<=y) return ai[node].maxi;
  59.     int m = (l+r)/2;
  60.     pii lans = {-1,-1}, rans = {-1,-1};
  61.     if (x<=m) lans = queryMax(node<<1,l,m,x,y);
  62.     if (y>m) rans = queryMax(node<<1|1,m+1,r,x,y);
  63.     if (lans.first!=-1 && rans.first!=-1)
  64.         return (lans.first > rans.first ? lans : rans);
  65.     if (lans.first!=-1)
  66.         return lans;
  67.     return rans;
  68. }
  69. lld eu(int x)
  70. {
  71.     lld ret = x;
  72.     for (unsigned i=0;i<primes.size() && primes[i]*primes[i]<=x;++i)
  73.     {
  74.         if (x%primes[i]) continue;
  75.         ret -= (ret/primes[i]);
  76.         while (x%primes[i]==0)
  77.             x/=primes[i];
  78.     }
  79.     if (x>1)
  80.         ret-=(ret/x);
  81.     return ret;
  82. }
  83. lld queryAns(int node, int l, int r, int x, int y)
  84. {
  85.     if (x<=l && r<=y) return ai[node].euv;
  86.     int m = (l+r)/2;
  87.     lld v1=-1, v2=-1;
  88.     if (x<=m)
  89.         v1 = queryAns(node<<1,l,m,x,y);
  90.     if (y>m)
  91.         v2 = queryAns(node<<1|1,m+1,r,x,y);
  92.     if (v1!=-1 && v2!=-1)
  93.         return computeAns(v1, v2);
  94.     if (v1!=-1)
  95.         return v1;
  96.     return v2;
  97. }
  98. void erath()
  99. {
  100.     prime[0] = prime[1] = 1;
  101.     for (int i=2;i<=maximum;++i)
  102.         if (!prime[i])
  103.         {
  104.             primes.push_back(i);
  105.             for (int j=i+i;j<=maximum;j+=i)
  106.                 prime[j] = 1;
  107.         }
  108. }
  109. int main()
  110. {
  111.     /*freopen("in","r",stdin);
  112.     freopen("out","w",stdout);*/
  113.     scanf("%d",&n);
  114.     for (int i=1;i<=n;++i)
  115.     {
  116.         scanf("%d",&a[i]);
  117.         if (a[i]>maximum) maximum = a[i];
  118.     }
  119.     erath();
  120.     for (int i=1;i<=n;++i)
  121.         v[i] = eu(a[i]);
  122.     build(1, 1, n);
  123.     int q;
  124.     int ind1, ind2;
  125.     lld v1, v2, v3, v;
  126.     pii gr, ls;
  127.     scanf("%d",&q);
  128.     for (int i=1;i<=q;++i)
  129.     {
  130.         scanf("%d %d",&l,&r);
  131.         v1 = v2 = v3 = v = 1;
  132.         gr = queryMax(1,1,n,l,r);
  133.         ls = queryMin(1,1,n,l,r);
  134.         if (gr.first == ls.first)
  135.         {
  136.             printf("%lld\n", queryAns(1, 1, n, l+2, r));
  137.             continue;
  138.         }
  139.         ind1 = gr.second;
  140.         ind2 = ls.second;
  141.         if (ind1 > ind2) swap(ind1, ind2);
  142.         if (l<ind1)
  143.             v1 = queryAns(1, 1, n, l, ind1-1);
  144.         if (ind2-ind1>=2)
  145.             v2 = queryAns(1, 1, n, ind1+1, ind2-1);
  146.         if (ind2<r)
  147.             v3 = queryAns(1, 1, n, ind2+1, r);
  148.         v = computeAns(v1, v2);
  149.         v = computeAns(v, v3);
  150.         printf("%lld\n", v);
  151.     }
  152.     /*fclose(stdin);
  153.     fclose(stdout);*/
  154.     return 0;
  155. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement