CF1220
A
1と0、それぞれレイド文字「N」と「Z」
その数は、出力することができます
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
#define min std::min
#define max std::max
const int N = 3e5 + 3;
char s[N];
int sum[N];
int n;
inline int read(){
int v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 + ch - 48;
ch = getchar();
}
return v * c;
}
int main(){
n = read();
scanf("%s",s + 1);
for(int i = 1;i <= n;++i) sum[s[i]]++;
int cnt = 0;
while(sum['n']){
cnt++;
printf("1 ");
sum['n']--;
}
while(sum['z']){
printf("0 ");
sum['z']--;
}
return 0;
}
B
あなたは与える\(N * N \)行列、\((i、j)は\ ) に代表される位置\(a_iを\タイムズa_j \) (対角線\(0 \) )
配列を探している\(\)を
任意の3のために\((I、J、K )\)
我们有の\(a_iを^ 2 = \ FRAC {\回a_j a_iを\回\回a_k a_j} {a_j \回a_k} \)
このようにして、それぞれについて決定することができます\(^ a_iを2 \) 、そして最後に根を開くために
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
#define min std::min
#define max std::max
const int N = 1005;
LL a[N][N];
LL ans[N];
int n,m;
inline int read(){
int v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 + ch - 48;
ch = getchar();
}
return v * c;
}
int main(){
n = read();
for(int i = 1;i <= n;++i) for(int j = 1;j <= n;++j) a[i][j] = read();
for(int i = 1;i <= n;++i){
int x = 0,y = 0;
if(i <= n - 2) x = i + 1,y = i + 2;
else if(i == n - 1) x = 1,y = n;
else x = 1,y = 2;
ans[i] = a[i][x] * a[i][y] / a[x][y];
}
for(int i = 1;i <= n;++i) printf("%.0lf ",sqrt((double)ans[i]));
return 0;
}
C
文字列が与えられ\(S \)
ゲームのルール
現在\([L、R]が\ ) のみに拡張することができる([L 'R'を\ ] \) ように\(L '\ルL、 R \ GE器R \) と\(S [L' 、R「] \)より辞書順\(S [L、R]が \) 小さい、相手が勝つために時間を取ることができません
それぞれのための\(Iは\)の初期状態であるときに得られる、\([I、I] \ ) 、上側のハンド勝った場合
明らかに、限りそことして(S [L「R \ 」] \) のみ、我々は今の状態に状態で存在するよりも辞書以下であるか否かを決定する必要がある、上部手が最適解に移動できるようになり、条件を満たし
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
#define min std::min
#define max std::max
const int N = 1e6 + 3;
char s[N];
int sum[27][N];
int n;
int ans = 0x3f3f3f3f;
inline int read(){
int v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 + ch - 48;
ch = getchar();
}
return v * c;
}
int main(){
scanf("%s",s + 1);
n = strlen(s + 1);
for(int i = n;i >= 1;--i){
for(int j = 0;j < 26;++j) sum[j][i] = sum[j][i + 1];
sum[s[i] - 'a'][i]++;
}
for(int i = 1;i <= n;++i){
bool flag = 0;
for(int j = s[i] - 'a' - 1;j >= 0;--j) if(sum[j][1] - sum[j][i] > 0) flag = 1;
if(!flag)
printf("Mike\n");
else printf("Ann\n");
}
return 0;
}
D
タイトル効果:正の整数の集合を考えると(Bの\)\。
すべての整数は有向グラフ中の頂点ではありませんしましょう。\(I、Jの\)の場合に限り、間のエッジがある\(左\ | - I〜J \権| \はB \で)
今から\(B \)これは、図に非二部グラフとなるように、前記要素を削除することによって。
奇数の不在リング:第二部グラフを定義します
まず、のための\(B \)要素\(X、Yの\)
もし
\ [\ dfrac {LCM(X
、Y)} {X} + \ FRAC {LCM(x、y)は} {Y}は\] この式は奇数である場合、奇数のリングがあります
私たちは、分類を議論します
場合\(X、Yの\)が奇数であります
次いで、上記の式は、偶数でなければなりません
場合\(X、Yの\)は偶数奇数の一つであり、次いで、上記の式は、偶数であります
場合は\(X、Yの\は)さえあります
その後、我々はセット\(X = 2X 'を、Y = 2Y' \)
これは、子供が、彼らは共存できるかどうかを判断することができるようになります奇数、偶数つまたはすべての奇数になるまで、問題になることがわかりました
第三の場合に見られることは本質的に2つの0の二進数のある端部と同じです
(他の2つは連続パリティを決定するため)
だから我々は、0の数が同じの終わりに共存させることができ、より多くの2でプッシュし、最終的な答えは\(N \)マイナス最大のグループ
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
#define min std::min
#define max std::max
const int N = 5e5 + 3;
inline LL read(){
LL v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 + ch - 48;
ch = getchar();
}
return v * c;
}
int n;
LL a[N];
LL num[N];
int cnt[N];
int main(){
n = read();
for(int i = 1;i <= n;++i) a[i] = read();
for(int i = 1;i <= n;++i){
LL x = a[i];
while((x & 1) == 0){
num[i]++;
x >>= 1;
}
cnt[num[i]]++;
}
int sum = 0,id = 0x3f3f3f3f;
for(int i = 0;i <= n;++i)
if(sum < cnt[num[i]]) sum = cnt[num[i]],id = num[i];
printf("%d\n",n - sum);
for(int i = 1;i <= n;++i){
if(num[i] != id) printf("%lld ",a[i]);
}
return 0;
}
E
効果の対象に
連続的に同じエッジを通過していない、少し右のポイントを表示する(非負)フリー所与\(S \)そのような出発点と(一度繰り返しにより算出)最大重量その経路
(図では少し奇妙な、黄色のドットは非環状に属しているように定義された本明細書中にループが見えます)
まず、そこリングはこの点は、その後、であり、我々はリング上のすべてのであれば渡すことができます
したがって、我々は貢献を考えるだけで必要箇所に入れ、その後、場合、我々はこの時点に入ったことが判明していません
私はもう戻って行くことはできません
例えば、黄色のドットプロットは、かつて私たちがリングから行って、あなただけのダウン行くことができます
我々はポイントの残りの部分が最大にポイントと右ポイントを受け継がれていなかった後、次に起動し、ポイントの片側に置く、とするために選択したポイントに行かなければなりません
このプロセスを実装する方法を検討し、すべての最初は、リングを見つけます
あなたは、すべての貢献をカウントすることができ、あなたはリング上でその点を証明することができ、トポロジカルソートのループを見つけるためにクラスを使用することができます
我々は、最大パスのように見えています
しかし、我々は、その後の状況とリング上の議論のための唯一の出発点であることに注意してください
出発点は、リングにない場合は、最適解は次のようになります。
ブルーセクション
すなわち、\(S \)一定の寄与部分となっているリングパスに
(でも最適解ならば\(S \)下、我々はダウンし、その後上がるとすることができます)
これはマークもだけで結構です
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
#define min std::min
#define max std::max
const int N = 5e5 + 3;
LL w[N];
struct edge{
int to;
int nxt;
}e[N << 1];
LL f[N];
int n,m;
LL ans,res;
int s;
inline int read(){
int v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 + ch - 48;
ch = getchar();
}
return v * c;
}
int tot,cnt;
int head[N],d[N];
bool used[N],flag[N];LL dp[N];
int fa[N];
inline void add(int x,int y){
e[++tot].to = y;
e[tot].nxt = head[x];
head[x] = tot;
}
inline void pre(){
flag[s] = 1;
std::queue <int> q;
for(int i = 1;i <= n;++i) if(d[i] == 1) q.push(i),f[i] = w[i];
while(!q.empty()){
int k = q.front();used[k] = 1;q.pop();
for(int i = head[k];i;i = e[i].nxt){
int y = e[i].to;
if(used[y]) continue;
f[y] = max(f[y],f[k] + w[y]);
flag[y] |= flag[k];
d[y]--;
if(d[y] == 1) q.push(y);
}
}
}
inline void dfs(int x,int f){
for(int i = head[x];i;i = e[i].nxt){
int y = e[i].to;
if(y == f) continue;
dfs(y,x);
dp[x] = max(dp[x],dp[y]);
}
dp[x] += w[x];
}
int main(){
n = read(),m = read();
for(int i = 1;i <= n;++i) w[i] = read();
for(int i = 1;i <= m;++i){
int x = read(),y = read();
add(x,y);
add(y,x);
d[x]++,d[y]++;
}
s = read();
if(m == n - 1){
dfs(s,0);
printf("%lld\n",dp[s]);
return 0;
}
pre();
for(int i = 1;i <= n;++i) if(flag[i]) ans += w[i],f[i] = 0;
for(int i = 1;i <= n;++i){
if(flag[i]) continue;
if(used[i]) res = max(res,f[i]);
else ans += w[i];
}
printf("%lld\n",ans + res);
return 0;
}