P9027 题解
题目大意
已经说的很清楚了。
解题思路
首先,如果
但是单单满足这个还不够,这只能保证
我们考虑贪心。显然,
因此构造方案就是对于任意
接下来讲如何判断方案是否合法,即判断 impossible 的情况。由于
参考代码
#include<bits/stdc++.h>
#define maxn 150010
using namespace std;
typedef long long ll;
struct node{
ll x,y,z;
}ask[maxn];
ll n,a[maxn],m,x,y,z,f[maxn][20],b[maxn][20];
ll c[maxn],st[maxn][20],save,lo[maxn],num;
ll gcd(ll x,ll y){
if(x==0)return y;
return gcd(y%x,x);
}
ll lcm(ll x,ll y){
return x/gcd(x,y)*y;
}
bool flag;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)c[i]=1;
for(int i=1;i<=m;i++){
cin>>x>>y>>z;
ask[i]=node{x,y,z};
f[x][z]++;f[y+1][z]--;
}
for(int i=1;i<=16;i++)
for(int j=1;j<=n;j++)
b[j][i]=b[j-1][i]+f[j][i];
for(int i=1;i<=n;i++)
for(int j=1;j<=16;j++)
if(b[i][j]>0)
c[i]=lcm(c[i],j);
for(int i=1;i<=n;i++)st[i][0]=c[i];
for(int i=2;i<=n;i++)lo[i]=lo[i/2]+1;
for(int j=1;j<=19;j++)
for(int i=1;i<=n;i++)
if(i+(1<<j)-1<=n)
st[i][j]=gcd(st[i][j-1],st[i+(1<<j-1)][j-1]);
flag=1;
for(int i=1;i<=m;i++){
x=ask[i].x;y=ask[i].y;z=ask[i].z;
save=lo[y-x+1];
num=gcd(st[x][save],st[y-(1<<save)+1][save]);
// cout<<num<<endl;
if(num!=z)flag=0;
}
if(!flag)cout<<"Impossible"<<endl;
else{
for(int i=1;i<=n;i++)
cout<<c[i]<<" ";
cout<<endl;
}
return 0;
}