专栏文章
P11312 神奇的小江鸟
P11312题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mir076c1
- 此快照首次捕获于
- 2025/12/04 13:36 3 个月前
- 此快照最后确认于
- 2025/12/04 13:36 3 个月前
题意简述
给定 个区间 ,求出是否
若存在,则输出
Yes和每个 的值;否则,输出No。思路(考场)
观察部分分:
-
:直接输出所有区间内的任意一个位置
-
;直接 DFS 暴力搜索
-
类似埃氏筛的方法,把 从 往大枚举, 的倍数就筛去不用再判断了。
代码
CPP#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
#define ld long double
inline ll read(){
ll res = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9'){
if(c == '-')f = -1;
c = getchar();
}
while(c >= '0' && c <= '9'){
res = res * 10 + c - '0';
c = getchar();
}
return f * res;
}
const int N = 20010;
struct ii{
ll l, r;
int i;
bool operator<(const ii & a)const{
if(l == a. l)return r < a. r;
return l < a. l;
}
}a[N];
unordered_map<ll, bool>ma;
ll ans[N];
ll n, k;
ll mid[N];
ll gcd(ll a, ll b){
if(b == 0)return a;
return gcd(b, a % b);
}
bool dfs(int deep){
if(deep == n + 1){
ll now = mid[1];
for(int i = 2; i <= n; i ++){
now = gcd(now, mid[i]);
}
if(now >= k){
cout << "Yes" << endl;
for(int i = 1; i <= n; i ++)cout << mid[i] << ' ';
cout << endl;
return 1;
}
return 0;
}
for(int i = a[deep]. l; i <= a[deep]. r; i ++){
mid[deep] = i;
if(dfs(deep + 1))return 1;
}
return 0;
}
signed main(){
ll t = read();
while(t --){
ma. clear();
n = read(), k = read();
ll maxx = 0;
bool flagg = 0;
for(int i = 1; i <= n; i ++){
a[i]. l = read();
a[i]. r = read();
if(a[i]. l != a[i]. r)flagg = 1;
a[i]. i = i;
maxx = max(maxx, a[i]. r);
}
if(flagg == 0){
ll now = a[1]. l;
for(int i = 2; i <= n; i ++){
now = gcd(now, a[i]. l);
}
if(now >= k){
cout << "Yes" << endl;
for(int i = 1; i <= n; i ++)cout << a[i]. l << ' ';
cout << endl;
}
else cout << "No" << endl;
continue;
}
if(k == 1){
cout << "Yes" << endl;
for(int i = 1; i <= n; i ++){
cout << a[i]. l << ' ';
}
cout << endl;
continue;
}
if(n <= 10){
if(!dfs(1))cout << "No" << endl;
continue;
}
sort(a + 1, a + 1 + n);
bool flag = 0;
for(ll i = k; i <= maxx; i ++){
if(ma[i]){
ma. erase(i);
continue;
}
int idx = 1;
for(ll j = 1; j <= maxx / i; j ++){
ma[i * j] = 1;
while(i * j >= a[idx]. l){
if(i * j > a[idx]. r)break;
ans[a[idx]. i] = i * j;
idx ++;
if(idx > n)break;
}
if(idx > n)break;
if(i * j > a[idx]. r)break;
}
if(idx == n + 1){
cout << "Yes" << endl;
for(int i = 1; i <= n; i ++){
cout << ans[i] << ' ';
}
cout << endl;
flag = 1;
break;
}
}
if(!flag)cout << "No" << endl;
}
return 0;
}
思路(正解)
当所有区间长度都 时,一定都可以选到。所以我们直接把所有区间内的合法情况输出就可以。
当存在区间的长度 时,我们可以先按区间长度排序,保证第一个区间一定合法,这样子我们就可以把第一个区间的 个数的所有 因数都存到一个集合里,并依次判断他是否可以满足所有集合。( 的数里面最多只有 个质因数,所以因数个数也很少,可以通过)
代码
CPP#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
inline ll read(){
ll res = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9'){
if(c == '-')f = -1;
c = getchar();
}
while(c >= '0' && c <= '9'){
res = res * 10 + c - '0';
c = getchar();
}
return res * f;
}
const int N = 20010;
struct ii {
ll l, r;
int i;
bool operator<(const ii & a)const{
return r - l + 1 < a. r - a. l + 1;
}
}q[N];
ll ans[N];
signed main(){
ll t = read();
while(t --){
ll n = read(), k = read();
for(int i = 1; i <= n; i ++){
q[i]. l = read(), q[i]. r = read();
q[i]. i = i;
}
sort(q + 1, q + 1 + n);
if(q[1]. r - q[1]. l + 1 >= k){
for(int i = 1; i <= n; i ++){
ans[q[i]. i] = q[i]. r / k * k;
}
printf("Yes\n");
for(int i = 1; i <= n; i ++){
printf("%lld ", ans[i]);
}
printf("\n");
continue;
}
ii sm = q[1];
set<ll>s;
for(ll i = sm. l; i <= sm. r; i ++){
for(ll y = 1; y <= sqrt(i); y ++){
if(i % y == 0){
if(y >= k)s. insert(y);
if(i / y >= k)s. insert(i / y);
}
}
}
bool have_ans = 0;
for(auto it = s. begin(); it != s. end(); it ++){
ll now = *it;
bool flag = 0;
for(int i = 1; i <= n; i ++){
if(q[i]. l / now != q[i]. r / now){
ans[q[i]. i] = q[i]. r / now * now;
}
else if(q[i]. l % now == 0){
ans[q[i]. i] = q[i]. l;
}
else if(q[i]. r % now == 0){
ans[q[i]. i] = q[i]. r;
}
else{
flag = 1;
break;
}
}
if(!flag){
printf("Yes\n");
for(int i = 1; i <= n; i ++){
printf("%lld ", ans[i]);
}
printf("\n");
have_ans = 1;
break;
}
}
if(!have_ans)printf("No\n");
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...