Codeforces Round 924 (Div. 2)

A

判断下切割偶数边后拼接的图形与原图是否相同即可.

#include<bits/stdc++.h>
using namespace std;
#define LL long long
int t;
LL n,m;
bool solve() {
    if(n % 2ll == 0ll) {
        if(2ll*m != n) return true;
    }
    if(m % 2ll == 0ll) {
        if(2ll*n != m) return true;
    }
    return false;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin>>t;
    while(t--) {
        cin>>n>>m;
        if(solve()) cout<<"Yes\n";
        else cout<<"No\n";
    }
    return 0;
}

B

排序后双指针.

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=2e5+10;
int t,n,a[N],b[N],num[N];
int ans;
void solve() {
    sort(a+1,a+n+1);
    int cnt=0;
    ans=0;
    for(int i=1;i<=n;i++) {
       if(a[i] != a[i-1]) b[++cnt]=a[i];
    }
    for(int l=1,r=1;r<=cnt;r++) {
        while(l < r && b[r] - b[l] >= n) l++;
        ans=max(ans,r-l+1);
    }
    cout<<ans<<"\n";
    return;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin>>t;
    while(t--) {
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        solve();
    }
    return 0;
}

C

推下式子可以发现,一个 $k$ 当且仅当 $ (2k-2)\vert(n-x) $ 或 $ (2k-2)\vert(n+x-2) $ 且 $ k > x-1 $ 时合法。所以我们直接枚举 $n-x$ 与 $n+x-2$ 的因数判断是否合法,注意要用set去重.

#include<bits/stdc++.h>
using namespace std;
#define LL long long
int t,x,n;
set<int> s;
void add(int p) {
    if(p & 1) return;
    p/=2; p++;
    if(p >= x) s.insert(p);
    return;
}
void solve() {
    int ans=0;
    for(int i=1;i*i<=n-x;i++) {
        if((n-x) % i == 0) {
            add(i); add((n-x)/i);
        }
    }
    for(int i=1;i*i<=n+x-2;i++) {
        if((n+x-2) % i == 0) {
            add(i); add((n+x-2)/i);
        }
    }
    ans=s.size();
    s.clear();
    cout<<ans<<"\n";
    return;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin>>t;
    while(t--) {
        cin>>n>>x;
        solve();
    }
    return 0;
}

D

设 $f(x,y)$ 表示将 $x$ 个人分到 $y$ 组可产生的贡献,那么在分为 $k$ 组时的总收益为 $ \sum_{i=1}^nb\ast f(c\lbrack i\rbrack,k)-(k-1)\ast x $.容易发现(?)这是单峰的,可以用三分求最大值.

至于 $ f(x,y) $,记 $t=\left\lfloor\frac xy\right\rfloor $ $,u=x \, mod\, y$,利用组合知识我们可以给出表达式 $f(x,y) = \frac{u*(t+1)*(x-t-1)+t*(x-t)*(y-u)} 2 $.

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=2e5+10;
LL f(int x,int y) {
    LL t=x/y,u=x%y;
    LL xx=x,yy=y;
    return (u*(t+1ll)*(1ll*x-t-1ll)+t*(1ll*x-t)*(1ll*y-u))/2ll;
}
int t,n,b,x,c[N];
LL calc(int k) {
    if(k <= 1) return 0;
    LL ans=0;
    for(int i=1;i<=n;i++) ans+=1ll*b*f(c[i],k);
    ans-=(1ll*k-1ll)*x*1ll;
    return ans;
}
void solve() {
    int l=1,r=N,mid;
    LL ans=0;
    while(l <= r) {
        mid=(l+r)/2;
        if(calc(mid-1) <= calc(mid+1)) l=mid+1,ans=mid;
        else r=mid-1;       
        if(t < 0) cout<<"dg:"<<mid<<"\n";
    }
    cout<<max(max(calc(ans),calc(ans-1ll)),calc(ans+1ll))<<"\n";
    return;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin>>t;
    while(t--) {
        cin>>n>>b>>x;
        for(int i=1;i<=n;i++) cin>>c[i];
        solve();
    }
    return 0;
}

E

设 $x_0 = x \, mod \, y$,最后所填数的总和一定会表现为 $s = nx_0 + ky$ 的形式.于是我们便可以将问题变为构造一个长度为 $n$ 的序列使其满足 $a_1 = \left\lfloor\frac xy\right\rfloor ,a_{i+1} = 0 \; or \; a_{i+1} =a_i + 1$ 且 $\frac{s-n\ast x_0}y = \sum_{i=1}^na_i $.

考虑dp,设 $f_i$ 为数列和为 $i$ 时的最短方案长度,则转移方程如下:

$ f_i=f_{i-\sum_{k=0}^jk}+j+1 $

$j$ 是 $\sqrt n $ 级别的,$k$的和式可以$O(1)$ 求解,总复杂度$O(n\sqrt n)$.

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=2e5+10;
int t,n,x,y,s;
LL dp[N];
void solve() {
    for(int i=1;i<=s;i++) dp[i]=1e9;

    for(int i=1;i<=s;i++) {
        for(int j=0,sum=0;j<=s;j++) {
            sum+=j;
            if(sum > i) break;
            if(dp[i-sum] + j + 1 < dp[i]) { 
                dp[i] = dp[i-sum] + j + 1;
            }
        }
    } 
    int sum=0;

    for(int i=1;i<=n;i++) {
        sum+=(x/y)+i-1;
        if(sum > s) break;
        if(dp[s-sum] + i <= n) {
            cout<<"Yes\n";
            for(int j=1;j<=i;j++) cout<<x+(j-1)*y<<" ";
            for(int p=s-sum;p;) {
                int val=0;
                for(int j=0;j<=p;j++) {
                    val+=j;
                    if(val > p) break;
                    if(dp[p] == dp[p-val]+j+1){
                        for(int k=0;k<=j;k++) cout<<x%y+k*y<<" ";
                        p-=val;
                        break;
                    }
                }
            }
            for(int j=1;j <= n-i-dp[s-sum];j++) cout<<x % y<<" ";
            cout<<"\n";
            return;
        } 
    }
    cout<<"No\n";
    return;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin>>t;
    while(t--) {
        cin>>n>>x>>y>>s;
        if((LL)n*(x%y) > (LL)s) {
            cout<<"No\n";
            continue;
        }
        s-=n*(x%y);
        if(s % y) {
            cout<<"No\n";
            continue;
        }
        s/=y;
        if(x/y > s) {
            cout<<"No\n";
            continue;
        }
        solve();
    }
    return 0;
}

F

唉数据结构

数学+线段树维护,等最近把手里的事做完再专门练练数据结构吧.

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇