CodeForces 474F Ant colony 【线段树】【gcd】【二分】
2016-10-13 19:24
477 查看
题目:点击打开链接
题意:给定一个数列,求出区间长度减去询问区间内能被区间内所有其他的数整除的数出现的个数的值。
思路:将原数列存进一个结构体,先按照数列的值从小到大排序,相同时按照数列编号从小到大排序,因为a%b==0等价为gcd(a,b)==b,所以我们可以通过线段树或者ST表预处理出所有区间内的gcd值,然后查找到对应区间内的gcd值,就是该区间内能被区间内所有其他的数整除的数,然后通过二分结构体找到满足值相同的值的两端的位置,相减即为该数的个数,再用区间长度减去个数即可。
代码:
//线段树版本
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <set>
#include <vector>
#include <map>
#define PR pair<int,int>
#define MP make_pair
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define sqr(x) ((x)*(x))
#define ll long long
#define ull unsigned __int64
const ll INF = 1e18;
const int inf=0x3f3f3f3f;
const int M=15;
const int N=100100;
const int MOD=100000;
const double eps=1e-10;
const double pi=acos(-1.0);
using namespace std;
int n,m;
int a[N<<2];
PR b
;
int cnt;
int gcd(int a,int b) {return b==0?a:gcd(b,a%b);}
void pushup(int rt)
{
a[rt]=gcd(a[rt<<1],a[rt<<1|1]);
}
void build(int l,int r,int rt)
{
if(l==r)
{
scanf("%d",&a[rt]);
b[++cnt].fi=a[rt];
b[cnt].se=cnt;
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) return a[rt];
int m=(l+r)>>1;
int x=0,y=0;
if(L<=m) x=query(L,R,lson);
if(m<R) y=query(L,R,rson);
return gcd(x,y);
}
int main()
{
int i,j;
scanf("%d",&n);
build(1,n,1);
sort(b+1,b+1+n);
scanf("%d",&m);
for(i=1;i<=m;i++)
{
int l,r;
scanf("%d%d",&l,&r);
int tmp=query(l,r,1,n,1);
int mi=lower_bound(b+1,b+1+n,MP(tmp,l))-b;
int mx=lower_bound(b+1,b+1+n,MP(tmp,r+1))-b;
printf("%d\n",r-l+1-(mx-mi));
}
}
题意:给定一个数列,求出区间长度减去询问区间内能被区间内所有其他的数整除的数出现的个数的值。
思路:将原数列存进一个结构体,先按照数列的值从小到大排序,相同时按照数列编号从小到大排序,因为a%b==0等价为gcd(a,b)==b,所以我们可以通过线段树或者ST表预处理出所有区间内的gcd值,然后查找到对应区间内的gcd值,就是该区间内能被区间内所有其他的数整除的数,然后通过二分结构体找到满足值相同的值的两端的位置,相减即为该数的个数,再用区间长度减去个数即可。
代码:
//线段树版本
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <set>
#include <vector>
#include <map>
#define PR pair<int,int>
#define MP make_pair
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define sqr(x) ((x)*(x))
#define ll long long
#define ull unsigned __int64
const ll INF = 1e18;
const int inf=0x3f3f3f3f;
const int M=15;
const int N=100100;
const int MOD=100000;
const double eps=1e-10;
const double pi=acos(-1.0);
using namespace std;
int n,m;
int a[N<<2];
PR b
;
int cnt;
int gcd(int a,int b) {return b==0?a:gcd(b,a%b);}
void pushup(int rt)
{
a[rt]=gcd(a[rt<<1],a[rt<<1|1]);
}
void build(int l,int r,int rt)
{
if(l==r)
{
scanf("%d",&a[rt]);
b[++cnt].fi=a[rt];
b[cnt].se=cnt;
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) return a[rt];
int m=(l+r)>>1;
int x=0,y=0;
if(L<=m) x=query(L,R,lson);
if(m<R) y=query(L,R,rson);
return gcd(x,y);
}
int main()
{
int i,j;
scanf("%d",&n);
build(1,n,1);
sort(b+1,b+1+n);
scanf("%d",&m);
for(i=1;i<=m;i++)
{
int l,r;
scanf("%d%d",&l,&r);
int tmp=query(l,r,1,n,1);
int mi=lower_bound(b+1,b+1+n,MP(tmp,l))-b;
int mx=lower_bound(b+1,b+1+n,MP(tmp,r+1))-b;
printf("%d\n",r-l+1-(mx-mi));
}
}
//ST版本 #include <stdio.h> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <set> #include <vector> #include <map> #define PR pair<int,int> #define MP make_pair #define fi first #define se second #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define sqr(x) ((x)*(x)) #define ll long long #define ull unsigned __int64 const ll INF = 1e18; const int inf=0x3f3f3f3f; const int M=18; const int N=100100; const int MOD=100000; const double eps=1e-10; const double pi=acos(-1.0); using namespace std; int n,m; int dp [M],a ; PR b ; int gcd(int a,int b) {return b==0?a:gcd(b,a%b);} int main() { int i,j; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&a[i]); b[i].fi=dp[i][0]=a[i]; b[i].se=i; } sort(b+1,b+1+n); for(j=1;j<18;j++) for(i=1;i+(1<<j)-1<=n;i++) dp[i][j]=gcd(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); scanf("%d",&m); for(i=1;i<=m;i++) { int l,r; scanf("%d%d",&l,&r); int k=log2(r-l+1); int tmp=gcd(dp[l][k],dp[r-(1<<k)+1][k]); int mi=lower_bound(b+1,b+1+n,MP(tmp,l))-b-1; int mx=lower_bound(b+1,b+1+n,MP(tmp,r+1))-b-1; printf("%d\n",r-l+1-(mx-mi)); } }
相关文章推荐
- CodeForces - 384E Propagating tree(DFS序 + 二分 + 线段树)
- Codeforces 460C 二分结果+线段树维护
- CodeForces 734C Anton and Making Potions 二分或线段树
- HDU 5726 GCD (rmq+二分 or 线段树 维护区间gcd)
- 文章标题 codeforces 75C:Modified GCD (二分+最大公因数)
- codeforces 75C C. Modified GCD(二分)
- Codeforces 609F Frogs and mosquitoes 二分+简单离散化线段树+Multimap
- codeforces 589G:线段树+二分
- CodeForces 474F Ant colony(线段树)
- 【HDU】5930 GCD【暴力+线段树二分】
- HDU5930 gcd (线段树 + 二分)
- HDU 5726 GCD(RMQ+二分)(线段树也可)
- Codeforces 359D Pair of Numbers【思维+二分+区间Gcd+区间最小值RMQ】
- 维护区间gcd(线段树 || ST表+二分)
- cf#305-D. Mike and Feet- 单调栈/ (线段树上二分)
- 51NOD 1421 最大MOD值&&Codeforces 484 B. Maximum Value(筛法 + 二分)
- codeforces 46D 线段树 区间合并
- CodeForces 359 D.Pair of Numbers (二分+ST)
- CodeForces - 363D Renting Bikes(二分,贪心)
- 【Codeforces 768 B Code For 1】+ 简单线段树