(树状数组)HDU - 4777 Rabbit Kingdom

 Long long ago, there was an ancient rabbit kingdom in the forest. Every rabbit in this kingdom was not cute but totally pugnacious, so the kingdom was in chaos in season and out of season.
  n rabbits were numbered form 1 to n. All rabbits' weight is an integer. For some unknown reason, two rabbits would fight each other if and only if their weight is NOT co-prime.
  Now the king had arranged the n rabbits in a line ordered by their numbers. The king planned to send some rabbits into prison. He wanted to know that, if he sent all rabbits between the i-th one and the j-th one(including the i-th one and the j-th one) into prison, how many rabbits in the prison would not fight with others.
  Please note that a rabbit would not fight with himself.

Input  The input consists of several test cases.
  The first line of each test case contains two integer n, m, indicating the number of rabbits and the queries.
  The following line contains n integers, and the i-th integer W i indicates the weight of the i-th rabbit.
  Then m lines follow. Each line represents a query. It contains two integers L and R, meaning the king wanted to ask about the situation that if he sent all rabbits from the L-th one to the R-th one into prison.
  (1 <= n, m, W i <= 200000, 1 <= L <= R <= n)
  The input ends with n = 0 and m = 0.
Output  For every query, output one line indicating the answer.Sample Input

3 2
2 1 4
1 2
1 3
6 4
3 6 1 2 5 3
1 3
4 6
4 4
2 6
0 0

Sample Output

2
1
1
3
1
2

        
 

Hint

  In the second case, the answer of the 4-th query is 2, because only 1 and 5 is co-prime with other numbers in the interval [2,6] .

题意:

给n个数,m次询问,每次询问一个区间,求该区间内有多少数与该区间其它数均互质。

 

首先,对于每一个数,都必存在一个最大的l和一个最小的r,满足下标在[l,r]区间内时与区间内所有其他数均互质。对于每次查询的区间,当且仅当[l,r]包含这个区间时,这个数才有贡献。

故我们可以考虑先预处理每个数的l和r,之后离线处理所有查询。先对所有查询按l从小到大,r从小到大的顺序排序,这样处理时就可以极大节省时间复杂度。

每次新查询的一个区间,就只需维护当前有多少符合条件的[l,r]区间。这只需要在上一次的基础上添加(add 1)和删除(add -1)即可。

  1 #include <iostream>
  2 #include <string>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <cstdio>
  6 #include <cmath>
  7 #include <queue>
  8 #include <set>
  9 #include <map>
 10 #include <list>
 11 #include <vector>
 12 #include <stack>
 13 #define mp make_pair
 14 //#define P make_pair
 15 #define MIN(a,b) (a>b?b:a)
 16 //#define MAX(a,b) (a>b?a:b)
 17 #define REP(I,N) for (I=0;I<N;I++)
 18 #define rREP(I,N) for (I=N-1;I>=0;I--)
 19 #define rep(I,S,N) for (I=S;I<N;I++)
 20 #define rrep(I,S,N) for (I=N-1;I>=S;I--)
 21 #define FOR(I,S,N) for (I=S;I<=N;I++)
 22 #define rFOR(I,S,N) for (I=N;I>=S;I--)
 23 typedef long long ll;
 24 typedef unsigned long long ull;
 25 const int MAX=2e5+5;
 26 const int INF=1e7+5;
 27 using namespace std;
 28 //const int MOD=1e9+7;
 29 typedef pair<ll,int> pii;
 30 const double eps=0.00000001;
 31 const int limit=2e5;
 32 int n,m;
 33 int c[MAX];
 34 inline int lowbit(int x)
 35 {
 36     return x&-x;
 37 }
 38 int presum(int x)//前缀和
 39 {
 40     int re=0;
 41     while(x)
 42     {
 43         re+=c[x];
 44         x-=lowbit(x);
 45     }
 46     return re;
 47 }
 48 int sum(int l,int r)
 49 {
 50     return presum(r)-presum(l-1);
 51 }
 52 void add(int x,int d)
 53 {
 54     while(x<=n+1)
 55     {
 56         c[x]+=d;
 57         x+=lowbit(x);
 58     }
 59 }
 60 void init(int n)
 61 {
 62     int i;
 63     FOR(i,1,n+1) c[i]=0;
 64 }
 65 struct node
 66 {
 67     int l,r,i;
 68 }Q[MAX];
 69 int ans[MAX];
 70 bool cmp(node a,node b)
 71 {
 72     if(a.l!=b.l)
 73         return a.l<b.l;
 74     else
 75         return a.r<b.r;
 76 }
 77 int prepos[MAX];
 78 int l[MAX],r[MAX];
 79 int a[MAX],b[MAX];
 80 vector<int>L[MAX];
 81 void solve()
 82 {
 83     int i,j,k;
 84     FOR(i,1,n) scanf("%d",&a[i]),b[i]=a[i];
 85     memset(prepos,0,sizeof(prepos));
 86     FOR(i,1,n)
 87     {
 88         l[i]=1;
 89         for(k=2;k*k<=a[i];k++)
 90         {
 91             if(a[i]%k==0)
 92             {
 93                 l[i]=max(l[i],prepos[k]+1);
 94                 while(a[i]%k==0)
 95                     a[i]/=k;
 96                 prepos[k]=i;
 97             }
 98         }
 99         if(a[i]>1)
100         {
101             k=a[i];
102             l[i]=max(l[i],prepos[k]+1);
103             prepos[k]=i;
104         }
105     }
106     FOR(i,1,limit) prepos[i]=n+1;
107     rFOR(i,1,n)
108     {
109         r[i]=n;
110         for(k=2;k*k<=b[i];k++)
111         {
112             if(b[i]%k==0)
113             {
114                 r[i]=min(r[i],prepos[k]-1);
115                 while(b[i]%k==0)
116                     b[i]/=k;
117                 prepos[k]=i;
118             }
119         }
120         if(b[i]>1)
121         {
122             k=b[i];
123             r[i]=min(r[i],prepos[k]-1);
124             prepos[k]=i;
125         }
126     }
127     FOR(i,1,n) vector<int>().swap(L[i]);
128     FOR(i,1,n) L[l[i]].push_back(i);
129     REP(i,m) scanf("%d%d",&Q[i].l,&Q[i].r),Q[i].i=i;
130     init(n);
131     sort(Q,Q+m,cmp);
132     int now1=0;
133     REP(i,m)
134     {
135         while(now1<Q[i].l)
136         {
137             if(now1)
138                 add(now1,-1),add(r[now1]+1,1);
139             now1++;
140             for(int k:L[now1])
141             {
142                 add(k,1);
143                 add(r[k]+1,-1);
144             }
145         }
146         ans[Q[i].i]=sum(Q[i].l,Q[i].r);
147     }
148     REP(i,m) printf("%d\n",ans[i]);
149 }
150 int main()
151 {
152     while(scanf("%d%d",&n,&m)&&(n||m))
153         solve();
154 }

 

posted @ 2017-07-27 21:53  perplex  阅读(239)  评论(0编辑  收藏  举报