Codeforces Round #777 (Div. 2)D,E
D. Madoka and the Best School in Russia
- 若一个数字能被d整除,那么其就是一个good数
- 若一个数字能够被称为上是一个beautiful数,第一它本身是一个good数,其次它不能够被分解为两个good数的乘积,也就是说它可以包含一个d和其他因子。
- 若一个数字能够以至少两种方式被分解为一个或者多个beautiful数的乘积的话,那么则输出YES,否则输出NO。
- 分类讨论
- 如果x分解出的d的个数小于2的话,那么直接输出NO。
- 如果x分解出的d的个数等于2的话,如果\(x/d^2\)是质数,输出NO,否则输出YES。
- 如果x分解出的d的个数大于等于3的话,如果\(x/d^{cnt}\)是一个合数的话,那么直接输出YES,否则尝试将d进行内部分解,使其分配到其他的d上。
- 特判 样例
128 4
,却输出NO,这个是因为\(128=4\times 4\times 4\times 2=4\times 4\times 8\),这时的4无法进行分解,否则将破坏beautiful数的定义。
- 特判 样例
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define MAX 1000005
#define MOD 1000000007
using namespace std;
const int N = 3E5+5,M = 6E5+10;
int x,d;
bool isprime(int k)
{
int p = sqrt(k);
for(int i=2;i<=p;i++)
if(k%i==0) return false;
return true;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)
{
cin>>x>>d;
int cnt = 0;
for(;x%d==0;x/=d) cnt++;
if(cnt<=1) cout<<"NO"<<endl;
else if(cnt==2)
{
if(isprime(x)) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
else if(cnt>=3)
{
if(!isprime(x)) cout<<"YES"<<endl;
else if(!isprime(d))
{
if(d==x*x&&cnt==3)
cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}else cout<<"NO"<<endl;
}
}
return 0;
}
E. Madoka and the Sixth-graders
-
题意:
-
有n个位置,规定坐在位置i的人在下一轮会到对应的位置进行坐下,若一个位置被多个人挤占,则保留编号小的,而其他编号的人直接进行淘汰,并从编号为n+1,...中按顺序进行补充。
-
由于每一轮的每一个位置转移的方向是固定的,所以空出的数量k也是固定的,于是可以拿出最后一轮中最大的数字减去n,来除去k,得到具体移动了几轮。
而我们可以通过倍增的思想快速得到第一轮任意一个位置在第n轮的位置。
-
空出的位置之所以会空出来,是因为这个位置上没有任何人移动到这个位置,同时这个位置上的人移动到了其他的位置,而每一轮这些位置上都会补充带有更大的数的人(相当于是炮灰),
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define MAX 1000005
#define MOD 1000000007
#define de(x) cout<<"de : "<<x<<endl;
using namespace std;
const int N = 1E5+5,M = 6E5+10;
int n,m,go[32][N],ans[N],fin[N],sta[N],end[N],num;
vector<int> ori[N],beat[N];
bool vis[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
set<int> st;
repd(i,1,n) cin>>go[0][i],st.insert(go[0][i]);
repd(i,1,n) cin>>fin[i];
repd(i,1,30) repd(j,1,n) go[i][j] = go[i-1][ go[i-1][j] ];
int maxn = *max_element(fin+1,fin+n+1);
num = (maxn-n)/(n-st.size());
repd(i,1,n)
{
int pos = i;
repd(j,0,30) if( num&(1<<j) ) pos = go[j][pos];
ori[pos].push_back(i);
}
repd(i,1,n)
{
if(fin[i]<=n)
{
sta[ ori[i][0] ] = fin[i];
vis[ fin[i] ] = 1;
rep(j,1,ori[i].size())beat[ fin[i] ].push_back(ori[i][j]);
}
}
set<int> open_st;
repd(i,1,n)
{
if(vis[i])
for(auto x:beat[i])
open_st.insert(x);
else
{
sta[ *open_st.begin() ] = i;
open_st.erase(open_st.begin());
}
}
repd(i,1,n)
cout<<sta[i]<<" ";
return 0;
}