首页 > 其他分享 >Codeforces Round 976 (Div. 2) 题解

Codeforces Round 976 (Div. 2) 题解

时间:2024-10-03 10:22:30浏览次数:1  
标签:976 cnt return 200005 int 题解 long solve Div

Codeforces Round 976 (Div. 2) 题解

2020B

一个常见的想法:开关灯=异或,虽然在这道题里没啥用
注意到,第i盏灯的按钮被按的次数就是i的除它本身以外的因子个数
而完全平方数的因子数为奇数,其他数的因子数为偶数

点击查看更多信息
#include<bits/stdc++.h>
using namespace std;
void solve()
{
    long long k;
    cin>>k;
    long long n;
    if(k<=100)n=1;
    else n=sqrt(k)-9;

    while(k>n*(n+1))n++;
    cout<<n*n+k-n*(n-1)<<endl;
   
}
int main()
{
    int T;
    cin>>T;
    while(T --> 0)
    {
        solve();
    }
    return 0;
}

2020C

大力分类讨论,按位判断,根据b,c,d的值判断a的值是可能存在,不存在还是已确定

查看代码
#include<bits/stdc++.h>
using namespace std;
void solve()
{
    long long b,c,d,ck=1;
    cin>>b>>c>>d;
    long long a=0;
    for(long long i=0;i<=60;i++)
    {
        long long tb=b&(1ll<<i);
        long long tc=c&(1ll<<i);
        long long td=d&(1ll<<i);
        if(td==0)
        {
            if(tb!=0&&tc==0)
            {
                ck=0;
                break;
            }else if(tb!=0)
            {
                a+=(1ll<<i);
            }
        }else
        {
            if(tb!=0&&tc==0);
            else if(tb!=0);
            else if(tc!=0)
            {
                ck=0;
                break;
            }else
            {
                a+=(1ll<<i);
            }
        }
    }
    if(ck)cout<<a<<endl;
    else cout<<-1<<endl;
    
}
int main()
{
    long long T;
    cin>>T;
    while(T --> 0)
    {
        solve();
    }
    return 0;
}

2020D

并查集。

注意到:d的范围很小,而我们只需要知道一个数和它的后十个数之间的联通关系就可以知道所有点之间的联通关系。因此我们定义一个n*10的数组,用来储存一个数和它之后的第d个数的联通关系。但是一次操作会影响很多数与它之后的第d个数的关系,我们采用差分的方式进行区间维护

查看代码
#include<bits/stdc++.h>
using namespace std;
int cnt[200005][12];
int f[200005];
int ct[200005];
int find(int x)
{
    if(f[x]==x)return x;
    return f[x]=find(f[x]);
}
void solve()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        f[i]=i;
        ct[i]=0;
        for(int j=1;j<=10;j++)cnt[i][j]=0;
    }
    for(int i=1;i<=m;i++)
    {
        int a,d,k;
        cin>>a>>d>>k;
        cnt[a][d]++;
        cnt[a+k*d][d]--;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=10;j++)
        {
            if(i+j>n)continue;
            if(i>=j)cnt[i][j]+=cnt[i-j][j];
            if(cnt[i][j]>0)f[find(i)]=find(i+j);
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        if(ct[find(i)]==0)ct[find(i)]=1,ans++;
    }
    cout<<ans<<endl;
}
int main()
{
    int T;
    cin>>T;
    while(T --> 0)
    {
        solve();
    }
    return 0;
}

2020E

首先我们需要明白,E(X^2) != E(X)E(X) ,而E(XY)=E(X)E(Y)的前提是X,Y独立(X,X显然不独立)

注意到值域很小,而时限很大,那么,我们采用一个暴力的想法,定义f[n][x]为前n个数完成选择后异或和为x的概率,然后所有的f[n][x]xx之和即为答案。

不过这么开数组会mle,我们用一个回滚数组即可

查看代码

#include<bits/stdc++.h>
using namespace std;
int pow(int a,int b,int p)
{
    int s=1;
    while(b)
    {
        if(b%2)s=1ll*s*a%p;
        a=1ll*a*a%p;
        b>>=1;
    }
    return s;
}
int a[200005],b[200005];
const int p=1e9+7;
int f[2][1024];
void solve()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    int m=pow(10000,p-2,p);
    for(int i=1;i<=n;i++)
    {
        cin>>b[i];
        b[i]=1ll*b[i]*m%p;
    }
    for(int j=0;j<=1023;j++)
    {
        f[1][j]=f[0][j]=0;
    }
    f[0][0]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=1023;j++)
        {
            f[1][j]=(1ll*f[0][j^a[i]]*b[i]%p+1ll*f[0][j]*(1-b[i]+p)%p)%p;
        }
        for(int j=0;j<=1023;j++)
        {
            f[0][j]=f[1][j];
        }
    }
    long long ans=0;
    for(int i=0;i<=1023;i++)
    {
        ans=(ans+1ll*i*i%p*f[0][i]%p)%p;
    }
    cout<<ans<<endl;

}
int main()
{
    int T;
    cin>>T;
    while(T --> 0)
    {
        solve();
    }
    return 0;
}


2020F

还没改出来,先咕咕咕

标签:976,cnt,return,200005,int,题解,long,solve,Div
From: https://www.cnblogs.com/arthalter/p/18445436

相关文章

  • 题解:CF1976D Invertible Bracket Sequences
    可以在cnblog中阅读。题意给一个合法括号序列,问有多少区间\([l,r]\),使得将区间内的每个括号翻转后,括号序列仍合法。分析十分套路地,我们将(看成\(+1\),将)看成\(-1\),则一个括号序列合法的充要条件是转换后的序列满足:前缀和任意位置非负;最后一项为\(0\)。考虑翻转......
  • ZZJC新生训练赛第二场题解
    先给出比赛链接:https://ac.nowcoder.com/acm/contest/92036A小红打怪ShowCodeAclassPoint{//点类public:intx,y;Point(){}Point(intx,inty):x(x),y(y){}Pointoperator+(constPoint&P)const{returnPoint(x+P.x,y+P.y);......
  • 题解:TopCoder12316 ThreeColorability
    Vjudge可以出成《三色绘恋》背景。题意给一个格点数为\((n+1)\times(m+1)\)的网格,给格点染色,相邻的格点不能染成同样的颜色。每个格子有一条对角线的边,可选N形和Z形。现在有一个残缺的网格,存在一些格子的对角线连法不确定,构造一种字典序最小的方案使得至少存在一种染色......
  • 树上最值路径 题解
    题意简述给你一棵\(n\)个结点的树,编号为\(1\simn\),求有多少路径\(\operatorname{Path}(u\rightarrowv)\),满足\(u=\max\{x\midx\in\operatorname{Path}(u\rightarrowv)\}\),\(v=\min\{x\midx\in\operatorname{Path}(u\rightarrowv)\}\)。......
  • Codeforces Round 975 (Div. 2)
    一万四参赛,VP赛时60A.MaxPlusSize一定选择最大值,若有多个最大值,优先选在奇数位置的最大值,后间隔涂上红色。#include<bits/stdc++.h>usingnamespacestd;constintN=105;intT,n,a[N];intmain(){ scanf("%d",&T); while(T--){ scanf("%d",&n); intm......
  • 题解:CF2014D Robert Hood and Mrs Hood
    差分,每次差分将\(\max(1,l-d+1)\)加\(1\),将\(r+1\)位置减\(1\)。然后前缀和求原数组,再遍历一下求最小值和最大值即可。代码:#include<bits/stdc++.h>usingnamespacestd;intmain(){ intt; cin>>t; while(t--){ intn,d,k; cin>>n>>d>>k;......
  • 题解:CF2009E Klee's SUPER DUPER LARGE Array!!!
    设\(m\)为\(a_1+\dots+a_i\),\(n\)为\(a_{i+1}+\dots+a_n\)。我们可以使用二分查找来搜索\(i\),使得\(m-n\)为最小的负数。如果我们移动到\(i+1\),则此时\(m-n\)为最小的整数。答案是两种情况下的最小绝对值。代码:#include<bits/stdc++.h>usingnamespacestd;pair<......
  • 题解:CF2009D Satyam and Counting
    比较容易观察的一道题,但是场上不开longlong见祖宗了。由于这题的\(x\)最大值比较小,所以我们可以直接存每个坐标是否有点。有两种三角形符号条件:存在两个点\((x,0),(x,1)\),可以观察到任意的其它点都可以成为第三点。有三个点为\((x,0),(x+1,1),(x+2,0)\)或\((x,1),(x+1......
  • 题解:CF2009C The Legend of Freya the Frog
    比较一眼的题目,场切了。分别考虑\(x\)和\(y\)。在\(x\)方向上我们需要的跳跃次数是\(\lceil\frac{x}{k}\rceil\),在\(y\)方向上我们需要的跳跃次数是\(\lceil\frac{y}{k}\rceil\)。考虑下面的两种情况:\(\lceil\frac{y}{k}\rceil\geq\lceil\frac{x}{k}\rceil......
  • 题解:P11137 [APC001] B - Checker
    注意到每个字符串长度相同,所以我们可以按照题意逐个遍历小K的题目和所有题库里的题目,统计相同位置字符相同的个数,如果大于\(\left\lceil\frac{k}{2}\right\rceil\),这两个题目就是重题。代码:#include<bits/stdc++.h>usingnamespacestd;boolc(stringa,stringb){in......