首页 > 其他分享 >Codeforces Round 940 (Div. 2) and CodeCraft-23 题解

Codeforces Round 940 (Div. 2) and CodeCraft-23 题解

时间:2024-04-25 10:46:08浏览次数:28  
标签:CodeCraft 23 int 题解 s1 s2 区间 偶个 define

Codeforces Round 940 (Div. 2) and CodeCraft-23 题解

题目链接

A. Stickogon 贪心

#include<bits/stdc++.h>

using namespace std;

#define ff first
#define ss second
#define pb push_back
#define all(u) u.begin(), u.end()
#define endl '\n'
#define debug(x) cout<<#x<<":"<<x<<endl;

typedef pair<int, int> PII;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 10, M = 105;
const int mod = 1e9 + 7;
const int cases = 1;

void Showball(){
   int n;
   cin>>n;
   vector<int> a(101);
   for(int i=0;i<n;i++){
     int x;
     cin>>x;
     a[x]++;
   }
   int ans=0;
   for(int i=1;i<=100;i++) ans+=a[i]/3;
   cout<<ans<<endl;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int T=1;
    if(cases) cin>>T;
    while(T--)
    Showball();
    return 0;
}

B. A BIT of a Construction 贪心

题意:给你 \(n\) 和 \(k\),构造出一个长度为 \(n\) 的数组,使得数组之和为 \(k\),并且使数组或起来的结果的1最多。

思路:为了让1的数量最多,我们直接取最接近 \(k\) 的 \(2^i-1\) 的数即可,剩下的补充即可。

void Showball(){
   int n,k;
   cin>>n>>k;
   if(n==1) return cout<<k<<endl,void();
   int t=__lg(k);
   int sum=(1<<t)-1;
   cout<<sum<<" "<<k-sum<<" ";
   if(n==2) return cout<<endl,void();
   for(int i=3;i<=n;i++) cout<<0<<" \n"[i==n];
}

C.How Does the Rook Move? DP|递推

题意:在一个 \(n\times n\) 的棋盘上放置棋子,若棋子坐标为 \((r,c)\),则 \(r\) 行 和 \(c\) 列的所有位置都不能再放置棋子,你和电脑对战,电脑每次会对称复制你的下法(将棋子放置到\((c, r)\) ) 。若你下在对称轴上,电脑跳过此回合,直到无法落子为止,求出棋盘终局有多少种情况。

思路:首先我们注意到,棋子一共只有两种走法,落在对称轴和非对称轴的方式。

并且棋子位置并不重要,我们可以平移。那么对于落在对称轴的情况,棋盘会变成 \((n-1)\times (n-1)\)

,只有一种情况。对于落在非对称轴的情况,期盼会变成 \((n-2)\times (n-2)\),一共有 \(2\times(n-1)\) 种情况。则显然可以得到递推式 \(f[i]=f[i-1]+2*(n-1)*f[i-2]\)。

对于一开始的落子情况,我们只需要维护好棋盘规模即可。

int f[N];
void init(){
   f[0]=1;
   f[1]=1;
   for(int i=2;i<N;i++){
      f[i]=(f[i-1]+2LL*(i-1)*f[i-2])%mod;
   }
}
void Showball(){
   int n,k;
   cin>>n>>k;
   while(k--){
      int x,y;
      cin>>x>>y;
      if(x==y) n--;
      else n-=2;
   }
   int ans=f[n];
   cout<<ans<<endl;
}

D. A BIT of an Inequality 拆位+算贡献+DP

题意:求出满足下列条件的三元组 \((x,y,z)\)的数量:

\(1\leq x\leq y\leq z \leq n\),

\(f(x,y)\)⊕ \(f(y,z) > f(x,z)\)。

其中 \(f(l,r)=a_l\) ⊕ \(a_{l+1}\) ⊕ ... ⊕ \(a_r\)。

思路:

看到异或数数题,经典的拆位+算贡献,前天小白月赛F题刚做过,这题稍微难一些。

根据异或的性质,右边比左边多异或一个 \(a_y\),值变小。让我们去计算这种情况的数量。

根据2进制的性质,最高位1的影响会超过后面所有1的影响,因此我们只需要处理 \(a_y\) 的最高位 \(1\) .

设最高位 \(1\) 为 \(t\),要满足值变小,说明区间其他数异或和第 \(t\) 位要为1。即区间其他数第 \(t\) 位 \(1\) 的

数量之和要为奇数。

问题转变成求出维护左右两每一位奇/偶个1的区间数量。

不妨定义 \(s1_{i,j,0/1}\)表示从 \(i\) 个开始往前选 第 \(j\) 位 有 奇/偶个 \(1\) 的区间数

如果当前位为 \(1\) , 那么奇区间和偶区间数量会互换,并且当前位自己构成一个奇区间。

\(s1[j][i][1]=s1[j-1][i][0]+1; s1[j][i][0]=s1[j-1][i][1];\)

反之,奇区间和偶区间数量不会互换,当前位自己构成一个偶区间。

\(s1[j][i][1]=s1[j-1][i][1]; s1[j][i][0]=s1[j-1][i][0]+1;\)

同理维护出从 \(i\) 个开始往后选 第 \(j\) 位 有 奇/偶个 \(1\) 的区间数

最后拆位,枚举 \(a_y\) 将贡献累加即可。

int s1[N][31][2];//从i个数往前选第j位 奇/偶个1的区间数
int s2[N][31][2];//从i个数往后选第j位 奇/偶个1的区间数
void Showball(){
   int n;
   cin>>n;
   vector<int> a(n+1);
   for(int i=1;i<=n;i++) cin>>a[i];
   for(int i=0;i<=n+1;i++){
      for(int j=0;j<=30;j++){
         s1[i][j][0]=s1[i][j][1]=0;
         s2[i][j][0]=s2[i][j][1]=0;
      }
   }
   for(int i=0;i<=30;i++){
      for(int j=1;j<=n;j++){
         if(a[j]>>i&1){
            s1[j][i][1]=s1[j-1][i][0]+1;
            s1[j][i][0]=s1[j-1][i][1];
         }else{
            s1[j][i][1]=s1[j-1][i][1];
            s1[j][i][0]=s1[j-1][i][0]+1;
         }
      }
      for(int j=n;j>=1;j--){
         if(a[j]>>i&1){
            s2[j][i][1]=s2[j+1][i][0]+1;
            s2[j][i][0]=s2[j+1][i][1];
         }else{
            s2[j][i][1]=s2[j+1][i][1];
            s2[j][i][0]=s2[j+1][i][0]+1;
         }
      }
   }

   LL ans=0;
   for(int i=1;i<=n;i++){
      int t=__lg(a[i]);
      ans=(ans+1LL*s1[i-1][t][1]*(1+s2[i+1][t][0]));
      ans=(ans+1LL*(s1[i-1][t][0]+1)*s2[i+1][t][1]);
   }
   cout<<ans<<endl;
}

标签:CodeCraft,23,int,题解,s1,s2,区间,偶个,define
From: https://www.cnblogs.com/showball/p/18157055

相关文章

  • [HNOI2005] 星际贸易 题解
    [HNOI2005]星际贸易将问题分为两次dp。题面有:“只有一种获得最大贸易额的方法”所以直接说明了贸易额与那些费用无关。有考虑到无论干啥都要维护,第二次\(dp\)直接以暗物质为核心即可对于这里\(R\)与\(n*2\)取\(min\)的一些细节理解。我们设计状态,因为观察到了暗......
  • 洛谷 P8989 [北大集训 2021] 随机游走 题解
    前言又是随机游走?题目分析看到加边,可能性太多了。但是为了让步数最大化,我们可以贪心地想,肯定要往前面连,而且越前面要走的期望步数肯定越大。并且,我们不会浪费边在终点上。于是,题目转变成了\(1\simn-1\)连向起点\(1\)连若干条边,使得随机游走到终点的期望步数最大。那要......
  • golang工具函数,把一个金额整型,单位为分,转成"1,231,111.00"格式的字符串
    这个函数首先将整数除以100来获取代表元的浮点数,然后格式化此数值为两位小数的字符串。接下来,函数将字符串分成整数和小数部分,并且为整数部分添加千位分隔符。最后,如果存在小数部分,它会将这两部分重新组合并返回正确格式化的金额字符串。为了正确地处理负数,我们需要先检查金额是......
  • [题解]P5431 【模板】模意义下的乘法逆元 2
    可恶,卡常好难受。P5431【模板】模意义下的乘法逆元2将分数通分,第\(i\)个分数是\(\frac{k^i*fac\diva[i]}{fac}\),\(fac\)表示所有元素的积。我们可以用\(lr,rl\)记录\(a\)的前缀后缀积,第\(i\)个分数就是\(\frac{k^i*lr[i-1]*rl[i+1]}{lr[n]}\)。这样分母都是\(lr[n]\),分子就......
  • 【专题】2023-2024年游客满意度调查报告合集PDF分享(附原数据表)
    原文链接:https://tecdat.cn/?p=36043游客不仅是旅游服务质量的最终评判者,还是旅游业的界定者、城市旅游的评价者,更是塑造国家级和世界级旅游城市的关键力量。他们的满意度直接揭示了旅游发展的动力与方向,为旅游城市的建设指明路径。2011年,我国荣获联合国世界旅游组织政策管理创新......
  • CISCN2023初赛-web复现
    Unzip       简单的软链接,都玩烂了。先创个软链接连接到/var/www/html,然后再创个同名文件夹,在这个文件夹下写马,传上去后等效在/var/www/html上写马,直接连接读flag就行了。deserbugjava审计。很显然的反序列化,bugstr传参。lib中出了hutool还有CC3.2.2,但CC自......
  • qoj3082 Ascending Matrix 题解
    题目链接点击打开链接题目解法不考虑第\(a_{r,c}=v\)的限制怎么求?我们把条件形式化一下,发现\(k\)个区域的颜色可以表示成轮廓线的形式,即第\(i-1\)条到第\(i\)条轮廓线之间的格点颜色为\(i\)问题变成找到\(k-1\)条互不穿过的路径,起点为\((1,m)\),终点为\((n,1)\)......
  • P2882 题解
    思想一眼看上去,没什么思路。看一下标签。枚举!于是枚举\(K\)。然后变成了求最少次数。由于枚举放在第一个,我们还是考虑一下枚举。我们枚举反转区间的左端点,我们惊奇地发现,由于从左往右扫,如果左端点是朝后的,那这次不转就没机会了。所以最最简单的暴力:从左往右扫,遇到左端点......
  • 「洛谷」题解:P1217 回文质数
    题目传送门看着题目好像很简单的样子,实际上做起来才会发现,这么多函数他奶奶的是普及-难度?在这道题目当中,我们最少需要写两个函数,如果需要优化可以再多写一个,待会儿的代码我们就直接放最简单版本的了。有人说这道题可以暴力对拍之后再输出,这完全可以,但是这么简单的题目不至于使用......
  • 2022ccpc题解
    2023年第五届河南省CCPC大学生程序设计竞赛ProblemA.Mocha上小班啦思路:求n个数位的最小值,条件:每一位数字都不同切不含前导零。只需要把0放到第二位,其他按从小到大输出,大于10以后输出-1即可。#include<bits/stdc++.h>usingnamespacestd;intmain(){//预处......