比赛链接:2017ICPCECIC
水了两题。。
D
设数组为
a
,长度为
答案是找出一个最大的
x
使得所有
如果一个数
如果所有
ai
都能降成
x
的倍数,那么数组的最大公约数是
这样对于一个
x
,想判断上述条件是否成立,只需要判断落在
可以维护一个前缀和
复杂度跟筛素数差不多,
O(nlogn)
。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+7;
int p[N],n,k;
int main()
{
while(~scanf("%d%d",&n,&k))
{
memset(p,0,sizeof(p));
int t,hh=0,dd=N;
for(int i=0;i<n;++i)
{
scanf("%d",&t);
hh=max(hh,t);
dd=min(dd,t);
++p[t];
}
for(int i=1;i<=hh;++i) p[i]+=p[i-1];
int ans;
for(ans = dd;ans > k+1;--ans)
{
t=ans;
int sum=0;
for(int i=0;i<=hh;i+=ans)
{
int l=i-1>=0?p[i-1]:0;
int r=i+k<=hh?p[i+k]:n;
sum+=r-l;
}
if(sum==n) break;
}
printf("%d\n",ans);
}
return 0;
}
H
将所有job根据赚的钱为下标存放到数组中。然后每个数组排好序。
那么对于赚到的钱为
x
的job,只能赚到的钱为
所以遍历一遍
x
,对于每个
复杂度为
O(n+m)
。
#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=2e5+7;
const int INF=1e9+7;
int n,m;
vector<pii> l[N],r[N];
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<m;++i)
l[i].clear(),r[i].clear();
for(int i=0;i<n;++i)
{
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
l[c].push_back(make_pair(x,y-x+1));
r[c].push_back(make_pair(y,y-x+1));
}
for(int i=1;i<m;++i)
{
sort(l[i].begin(),l[i].end());
sort(r[i].begin(),r[i].end());
}
int ans=INF;
for(int i=1;i<m;++i)
{
vector<pii>& x=l[i];
vector<pii>& y=r[m-i];
int xp=0,yp=0,yy=INF;
if(!x.size()||!y.size()) continue;
while(xp<x.size())
{
while(yp<y.size()&&y[yp].fi<x[xp].fi)
{
yy=min(y[yp].se,yy);
++yp;
}
ans=min(ans,yy+x[xp].se);
++xp;
}
}
if(ans!=INF) printf("%d\n",ans);
else puts("oh no!");
}
return 0;
}