Codeforces Round #641 (Div. 2)
ここはBCDの問題を補って、今度はやはりあまりに野菜で、ただaは2題だけあって、Dはまた間違っていて、cは少しもできません
トランスファゲート
B題 B題wa三発は惨めで、この時間は比較的ゆとりがあるので、いろいろな方法があって、最終的には基本的にDP です.本来考えていたのは、それぞれの数を分解して彼の因子を求め、因子を操作する である.または直接DPは、現在の数値の倍数を直接操作する である.ここでピットを比較したのはdist[i]=1で,もともと1にのみ初期値を付与していたが, の様子を思い浮かべた. a[1]=10,a[2]=1,a[3]=2,a[4]=3,ここでは出力2,2,4が該当するが,いずれも初期値1を付与しなければ出力は1のみであるため,この場所はピットである, に注意が必要である.
コード:
C問題の解題構想: C問題は少し複雑で、自分で長い間考えてやっと1つの複雑なやり方を理解して、あのlcmはまたgcdの読めないで、まだ を理解していませんまず質因子分解の構想 について述べる.まず我々が得た数は他質因子をres=p 1^k 1*p 2^k 2... に分解する次にp 1^k 1を例に挙げ、以下をp^k に簡略化する. p^kに対して、p^kは彼らのgcdから得たので、彼らが共有している です.そのため、私たちは彼らの数ごとに質量因子を分解し、vectorに 保存します.それから私たちは1~200000から、この範囲(入力データ範囲が1~200000のため)、私たちは順番に彼が値があるかどうかを判断します>=n-1 はなぜn−1なのか.n−1の数以上の質量因子が存在する限り、lcmの最後のgcdは現在の値 に存在することができるからである.数がnであれば、私は2番目に小さい位置を選んだ.2,4,8彼らのlcmのgcdは4に違いない.彼らは最も少ない2つの指数に拘束されているからだ.これは自分で を理解している.
次に、の数がn-1である場合、最小値をとることができる.これは、1ビットが欠けているため、最小値の影響を受ける である.そして彼らが乗算すれば
D問題の解題構想: D問題はC問題に比べて理解しやすいが、状況が少ないため、最初は を誤って理解した.ここでl-rの中位数を探すと、この中位数は値の中位数であり、下付きではない(問題を理解し間違えた) である.だからまずこの中にkがあるかどうかを判断して、もし存在するならば半分成功して、もし存在しないならば、もちろん“no” です次に、2つの条件が、2つの連続する>=kの値が存在するか否かを判断する.なぜなら、存在する場合、彼はすべての値を>=kに変更することができ、そして、もともとkが存在する場合、k に変更することができるからである.もう1つは、3つの連続する値のうち、2つの値>=kが存在するかどうかであり、3つの値のうち少なくとも2つの値>=kが存在するかどうか(これは最初の中位数の理解が間違っていた場所である)を探し、この2つの条件が結合すると「yes」になり、そうでなければ「no」になる. コード:
トランスファゲート
B題
コード:
#include
#include
#include
#include
#include
using namespace std;
const int N = 100010;
int a[N], dist[N];
int main(){
int t;
scanf("%d",&t);
while(t--){
memset(dist,0,sizeof dist);
int n;
scanf("%d",&n);
for (int i = 1; i <= n; i++){
scanf("%d",&a[i]);
dist[i] = 1;
}
for (int i = 1; i <= n; i++){ //
int x = i;
for (int j = 1; x * j <= n; j ++){
if (a[j * i] > a[i]) dist[i*j] = max(dist[i*j] ,dist[i] + 1);
}
}
int res = 0;
for (int i = 1; i <= n; i++){
res = max(res,dist[i]);
}
printf("%d
",res);
}
}
C問題の解題構想:
次に、
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int N = 200010;
vector<long long> ans[N];
ll mod_mult(ll a,ll b){ // a*b
ll res = 0;
ll exp = a;
while(b){
if (b&1){
res += exp;
}
exp<<=1;
b>>=1;
}
return res;
}
ll mod_exp(ll a,ll b){
ll res = 1;
ll exp = a ;
while(b){
if (b & 1) res = mod_mult(res,exp);
exp = mod_mult(exp,exp);
b>>=1;
}
return res;
}
ll pow_(ll a, ll b){
for (int i = 1; i<= b; i++){
a = a * a;
}
return a;
}
int main(){
int n;
scanf("%d",&n);
for (int i = 1; i <= n; i++){
int x;
scanf("%d",&x);
for (int j = 2; j * j <= x; j ++){
if (x % j == 0){
int cnt = 0;
while(x % j == 0){
cnt++;
x /= j;
}
ans[j].push_back(cnt);
}
}
if (x != 1) ans[x].push_back(1);
}
ll res = 1;
for (long long i = 1; i <= 200000; i++){
if (ans[i].size() >= n - 1){
sort(ans[i].begin(),ans[i].end());
if (ans[i].size() == n) res *= mod_exp(i,ans[i][1]);
else res *= mod_exp(i,ans[i][0]);
}
}
printf("%lld
",res);
return 0;
}
D問題の解題構想:
#include
#include
#include
using namespace std;
const int N = 100010;
int a[N];
int main(){
int t;
scanf("%d",&t);
while(t--){
int n, k;
scanf("%d%d",&n,&k);
int f = 0;
for (int i = 1; i <= n; i++){
scanf("%d",&a[i]);
if (a[i] == k) f = 1;
}
if (n == 1){
if (a[1] == k) puts("yes");
else puts("no");
continue;
}
int ff = 0;
for (int i = 1; i <= n; i++){
if (a[i] >= k){
if (i != n){
if (a[i + 1] >= k) ff = 1;
}
if (i < n - 1){
if (a[i + 2] >= k) ff = 1;
}
}
}
if (f && ff){
puts("yes");
}
else{
puts("no");
}
}
return 0;
}