首页 > 其他分享 >Codeforces Global Round 22

Codeforces Global Round 22

时间:2022-10-04 13:00:42浏览次数:95  
标签:return 22 int scanf Global Codeforces while include sim

题目链接

这场彻底打崩了,只做了 A,B,C ,可以看出我离退役已经不远力!

A. Glory Addicts

trash 题不写。感觉出得很没意思。

B. Prefix Sum Addicts

用 \(s_{n-k+1}\sim s_n\) 可以算出 \(a_{n-k+2}\sim a_n\) 。

另一方面,对于 \(a_1\sim a_{n-k+1}\) ,它们都不大于 \(a_{n-k+2}\) ,并且和为 \(s_{n-k+1}\) 。

容易得出结论:满足题意的 \(a\) 存在,当且仅当 \(a_{n-k+2}\sim a_n\) 单调不降,并且 \((n-k+1)a_{n-k+2}\ge s_{n-k+1}\) 。

View Code
#include<stdio.h>

const int N=1e5+5;

int T,n,k,s[N];

bool check() {
    if (k==1) return 1;
    for (int i=2; i<k; ++i)
        if (s[i]-s[i-1]>s[i+1]-s[i]) return 0;
    return 1ll*(n-k+1)*(s[2]-s[1])>=s[1];
}

int main() {
    scanf("%d",&T);
    while (T--) {
        scanf("%d%d",&n,&k);
        for (int i=1; i<=k; ++i)
            scanf("%d",s+i);
        puts(check()?"YES":"NO");
    }
    return 0;
}

C. Even Number Addicts

这题更是歌姬吧。

显然胜负只与奇数的个数、偶数的个数有关。

手玩小数据,找规律即可。

赛时大幅降智,好几次找的都是假规律,罚时罚麻了。

正确的规律见代码。

View Code
#include<stdio.h>

int T,n,x,s;

int main() {
    scanf("%d",&T);
    while (T--) {
        scanf("%d",&n),s=0;
        for (int i=1; i<=n; ++i)
            scanf("%d",&x),s+=(x&1); //s表示奇数个数
        if (s%4==0||s%4==3) puts("Alice");
        else if (s%4==2) puts("Bob");
        else puts((n-s&1)?"Alice":"Bob");
    }
    return 0;
}

D. Permutation Addicts

阅读理解题。真的离谱。不会出题可以不出。

我们观察 \(b\) 的定义,容易发现:若 \(x\le k\),则 \(b_x>k\) ;反之亦然。

因此,若 \(x<b_x\) ,则 \(k\ge x\) ;若 \(x>b_x\) ,则 \(k<x\) 。

于是我们可以通过 \(b\) 得到 \(k\) 与 \(x=1,2,\cdots,n\) 的大小关系,这样就确定了 \(k\) 。

接下来是求 \(a\) 的部分。

这个比较抽象,举个例子好了。

例如 \(n=8,k=5,a=[1,2,3,6,7,8,4,5]\) 。
计算可得 \(b=[9,9,9,3,3,3,6,6]\) 。

如果我们对于每个 \(x\) ,从 \(x\) 到 \(b_x\) 连一条边,那么图会长成这样:

img

然后就容易想到怎么求 \(a\) 了:

  1. 先找到根节点。(根节点一定是 \(0\) 或 \(n+1\) ,取度数不为 0 的那个)

  2. 根节点的所有儿子中,一定只有一个不是叶子节点,它必须放在其它儿子之后。(其它儿子之间可以随便排列)

  3. 以这个儿子为新的根节点,重复第 2 步。

代码如下。

View Code
#include<stdio.h>
#include<vector>

const int N=1e5+5;

int T,n,m,k,l,r,b[N],d[N],Q[N];
std::vector<int>E[N];

inline int max(int x,int y) { return x>y?x:y; }

void solve() {
    scanf("%d",&n),m=k=0;
    for (int i=0; i<=n+1; ++i)
        E[i].clear(),d[i]=0;
    for (int i=1; i<=n; ++i) {
        scanf("%d",b+i);
        E[b[i]].push_back(i),++d[b[i]];
        if (b[i]>i) k=max(k,i);
    }
    printf("%d\n",k);
    l=r=0,Q[0]=(d[0]?0:n+1);
    while (l<=r) {
        if (l) printf("%d ",Q[l]);
        int x=Q[l++];
        for (int i=0; i<d[x]; ++i)
            if (d[E[x][i]]) Q[++r]=E[x][i];
            else printf("%d ",E[x][i]);
    }
    putchar('\n');
}

int main() {
    scanf("%d",&T);
    while (T--) solve();
    return 0;
}

E. Balance Addicts

稍微思考之后可以发现,如果 \(a_i\) 均不为 0 ,那么这个题就会变得非常 sb 。

显然关键在于如何处理 0 。

首先,如果 \(a_1=a_2=\cdots=a_n=0\) ,那么随便划分即可,方案数为 \(2^n\) 。

否则,设 \(a\) 包含 \(x\) 个前缀 0 和 \(y\) 个后缀 0 。

先讨论 \(x,y\) 均不为 0 的情况,因为只有这种情况下,这些 0 会对总方案数产生影响。

考虑划分方案对应的 \(s\) ,显然 \(s\) 的两端各有 \(0\sim \min\{x,y\}\) 个 0 。

设 \(s\) 的两端各有 \(k\) 个 0 ,考虑在 \(a\) 中插板:

\[0~|~0~|~0~|~114~\cdots~514~|~0~|~0 \]

两端都要插 \(k\) 个板,因此方案数为 \(\dbinom xk\dbinom yk\) 。

那么可以写出式子:

\[f(1,n)=\left(\sum_{k=0}^{\min\{x,y\}}\binom xk\binom yk\right)f(1+x,n-y) \]

其中 \(f(l,r)\) 表示 \(a_l,\cdots,a_r\) 这个子段对应的答案。

然后是 \(xy=0\) 的情况,此时前缀 0 和后缀 0 不会影响划分方案数。

设 \(i,j\) 满足:\(a\) 中的前 \(i\) 个元素和后 \(j\) 个元素相等,并且 \(i,j\) 都最小。
双指针扫一下即可求出 \(i,j\) 。

如果 \(i=j=n\),那么显然 \(f(1,n)=1\) 。

否则,由 \(i,j\) 的最小性,我们可以得到:

  • \(a_1\sim a_i\) 与 \(a_{n-j+1}\sim a_n\) 一定没有公共元素,也就是说它们是不重叠的两段。
    假设有重叠部分,将其消去,则会得到更小的 \(i,j\) 。

  • 最终的划分方案中,这两段的内部都不能再断开。
    假设能断开,则同样会出现更小的 \(i,j\) 。

既然不能断开,那么可以认为 \(a_1\sim a_i\) 等价于一个前缀 0 ,\(a_{n-j+1}\sim a_n\) 等价于一个后缀 0 。

然后用和前面类似的方法处理即可。

时间复杂度为 \(O(n)\) ,因为每个位置只被访问到一次。

#include<stdio.h>
 
typedef long long ll;
 
const int N=1e5+5,P=998244353;
 
int T,n,a[N],fac[N],inv[N]; ll S;
 
inline int power(int x,int y) {
    int s=1;
    while (y) {
        if (y&1) s=1ll*s*x%P;
        x=1ll*x*x%P,y>>=1;
    }
    return s;
}
 
inline int C(int n,int m) {
    return 1ll*inv[n-m]*inv[m]%P*fac[n]%P;
}
 
int f(int l,int r) {
    if (!S) return power(2,r-l);
    int x=0,y=0;
    while (!a[l]) ++l,++x;
    while (!a[r]) --r,++y;
    if (x&&y) {
        int s=0;
        for (int i=0; i<=x&&i<=y; ++i)
            s=(1ll*C(x,i)*C(y,i)+s)%P;
        return 1ll*s*f(l,r)%P;
    }
    ll sl=0,sr=0;
    while (l<=r) {
        sl+=a[l],S-=a[l],++l;
        while (sr<sl) sr+=a[r],S-=a[r],--r;
        if (sl==sr) break;
    }
    if ((--l)<(++r)&&sl==sr)
        return a[l]=a[r]=0,f(l,r);
    return 1;
}
 
int main() {
    n=100000,fac[0]=1;
    for (int i=1; i<=n; ++i)
        fac[i]=1ll*fac[i-1]*i%P;
    inv[n]=power(fac[n],P-2);
    for (int i=n; i; --i)
        inv[i-1]=1ll*inv[i]*i%P;
    scanf("%d",&T);
    while (T--) {
        scanf("%d",&n),S=0;
        for (int i=1; i<=n; ++i)
            scanf("%d",a+i),S+=a[i];
        printf("%d\n",f(1,n));
    }
    return 0;
}

标签:return,22,int,scanf,Global,Codeforces,while,include,sim
From: https://www.cnblogs.com/REKonib/p/16748600.html

相关文章

  • 报告分享|2022全球手游玩家需求变化洞察报告
     报告链接:http://tecdat.cn/?p=287262020年全球疫情爆发,使人们居家和使用手机的时长增加,也带来了全球手游市场在过去两年的高增长。2022 年,海外手游市场增速开始放缓,但......
  • 报告分享|2022年智能汽车市场研究
     报告链接:http://tecdat.cn/?p=28731IDC将智能汽车市场定义为∶利用互联网、loT、人工智能、移动通信、云计算等技术,与汽车及交通基础设施相关的公司、产品和服务所组成......
  • 软件开发工具填空题_20221004
    1第三代程序设计语言一般都是(  )语言。进入二十一世纪以来,软件开发工具的发展有两个鲜明的特点,第一个特点是面向网络,另一个特点是(来源软件的兴起和运用)。填空题1712......
  • 2022.10.4markdown随笔
    Markdowm学习标题三级标题四级标题 字体helloworldhelloworldhelloworldhelloworld引用选择坚持,留住明天!分割线图片超链接点击跳转到哔哩哔哩列表......
  • CSP202209_3
    CSP202209_3目录CSP202209_3题目思路Code题目防疫大数据思路大模拟。大致题意就是针对当前天,给出以当天开始持续七天的风险地区。同时给出一定数量的用户信息,包括其......
  • Test 2022.10.04
    应该仍然是\(SHOI\)专场只写了两篇题解,另外两道题都有些超出知识范围了,当然第四题可以学一学改一改。T1门票一道链表哈希,理论\(map\)也能过,但是常数太大了,还是不足以过......
  • CSP-S 2022游记
    娱乐选手。Day-∞初赛84,太逊了!!!不过线只有52,过了。这种分数线真的有人过不了初赛吗......
  • 202209_2
    CSP202209_2目录CSP202209_2题目思路DFSDPCode题目何以包邮思路DFS直接DFS,对每件物品根据选与不选进行搜索。当前总价值已经大于答案或者已经满足条件了就显然没有搜......
  • CodeForces 1455G Forbidden Value
    洛谷传送门CF传送门小清新动态开点线段树优化dp题。首先题目中的if嵌套看起来就很烦,可以考虑建树,外面再套一层大的if0...end,这样就将本题转化成一个树上问题。......
  • Codeforces Round #823 (Div. 2) A-D
    比赛链接A题解知识点:贪心。对于一个轨道,要么一次性清理,要么一个一个清理。显然,如果行星个数大于直接清理的花费,那么选择直接清理,否则一个一个清理。即\(\sum\min(c,......