题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5223
题面:
2 2 2 1 2 1 1 2 2 2 1 1 2 2
Stupid BrotherK! 2 2
解题:出现不可能的情况是,A区间的长度比B的大,而公约数却比B大,那么是不可能发生的,排除掉这一点就可以了。因为数据量不大,先把每个位置初始值赋值为1,只要枚举过去,找出每一个位置和该区间的公约数C的公约数D,如果该位置的数能整除C,不做操作。如果不能整除就将该点的值乘上C/D(现在想想也不用分类,直接乘上C/D也行,两种方法效率上差不多 )这样出来就可以保证是最小值了。代码中的排序多此一举了。
代码:
#include <cstdio>
#include <algorithm>
using namespace std;
long long int store[1005];
struct info
{
long long int fm,to,val;
}storage[1005];
int gcd (long long int a,long long int b)
{
if(a==0)return b;
else return gcd(b%a,a);
}
bool cmp(info a,info b)
{
return a.val>b.val;
}
int main()
{
long long int n,q,l,r,tmp,cnt,x,t;
bool flag;
scanf("%I64d",&t);
while(t--)
{
scanf("%I64d%I64d",&n,&q);
cnt=0;
flag=true;
for(long long int i=1;i<=q;i++)
{
scanf("%I64d%I64d%I64d",&l,&r,&tmp);
storage[cnt].fm=l;
storage[cnt].to=r;
storage[cnt].val=tmp;
cnt++;
if(flag)
{
for(long long int j=0;j<cnt;j++)
{
if((l<=storage[j].fm&&r>=storage[j].to&&tmp>storage[j].val)||(storage[j].fm<=l&&storage[j].to>=r&&storage[j].val>tmp))
{
flag=false;
break;
}
}
}
}
if(flag)
{
//sort(storage+1,storage+n+1,cmp);
for(long long int j=1;j<=n;j++)
store[j]=1;
for(long long int j=0;j<cnt;j++)
{
l=storage[j].fm;
r=storage[j].to;
tmp=storage[j].val;
for(long long int k=l;k<=r;k++)
{
if(store[k]%tmp==0)
continue;
else
{
x=gcd(store[k],tmp);
store[k]*=tmp/x;
}
}
}
printf("%I64d",store[1]);
for(long long int i=2;i<=n;i++)
printf(" %I64d",store[i]);
printf("\n");
}
else
{
printf("Stupid BrotherK!\n");
}
}
return 0;
}
原文:http://blog.csdn.net/david_jett/article/details/45442725