文章目录

  • 关于学长太善良出了一道朴素差分题。
  • 派小星点星
  • 重生之我在异世界学差分
  • 最大连续子段的异或和
  • 肥波纳妾
  • 杨辉三角(Easy)
  • 取石子(pro plus max 版)
  • 重生之我在异世界遇到差分。

关于学长太善良出了一道朴素差分题。

题目大意:
给你一个n和m,分别表示区间的长度和操作的次数,然后m次询问每次有三个数l,r,c,表示区间 l 到r 的草长c单位的长度,问最后每个位置草长度为多少

这一题是差分的模板,不了解的话可以看这篇博客戳我查看

代码如下

#include<stdio.h>
int a[100005],b[100005];
int main(){int n,m;scanf("%d%d",&n,&m);int l,r,c;while(m--){scanf("%d%d%d",&l,&r,&c);b[l]+=c;b[r+1]-=c;}for(int i=1;i<=n;i++){b[i]+=b[i-1];printf("%d ",b[i]);}return 0;
}

派小星点星

给你一个n和m,分别表示区间的长度和操作的次数,之后输入n个整数,表示数组里的数,然后m次询问每次有三个数l,r,表示询问区间 l 到r 的总数是多少

同上题一样这是前缀和的模板,暴力做法会TLE,上面那篇博客也有前缀和的讲解

代码如下

#include<stdio.h>
int a[200005],b[200005];
int main()
{int n;scanf("%d",&n);for(int i=1;i<=n;i++)   scanf("%d",&a[i]);for(int i=1;i<=n;i++){b[i]=b[i-1]+a[i];}int q;scanf("%d",&q);while(q--){int l,r;scanf("%d%d",&l,&r);printf("%d\n",b[r]-b[l-1]);}return 0;
}

重生之我在异世界学差分

和第一道题一模一样,但是这道题不用差分做会超时,这里不再罗嗦了

最大连续子段的异或和

题目大意:
给出一个正整数序列,求异或和最大的连续子段和。

这道题数组很小,只有100,所以我们可以把每个区间都算一遍,代码中 i 相当于是左端点,j相当于是右端点,可以知道两重for循环可以不重不漏的把所有区间都算完。

代码如下:

#include<stdio.h>
int t[1005];
int main(){int n,ans=0;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&t[i]);for(int i=1;i<=n;i++){int sum=0;   //将sum设为0for(int j=i;j<=n;j++){sum^=t[j];if(sum>ans) ans=sum;   //每异或一次,就和答案取最大值}}   printf("%d\n",ans);return 0;
}

肥波纳妾

题目大意

第一行是询问的次数t,接下来每行一个整数n表示上面这个序列的第n个数是多少

从序列中我们可以发现第n个数是第n-1个数和第n-2个数的和,所以把前两个数输入进去,接下来的数都可以推出来

#include<stdio.h>
int a[50];
int main(){int t,n,i;a[1]=1,a[2]=1;scanf("%d",&t);for(i=3;i<=40;i++){a[i]=a[i-1]+a[i-2];}while(t--){scanf("%d",&n);printf("%d\n",a[n]);}return 0;
}

杨辉三角(Easy)

题目大意:

如果我们按杨辉三角从上到下、从左到右的顺序把所有数排成一列,可以得到如下数列:
1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, …
给定一个正整数 n ,请你输出数列中第一次出现 n 是在第几个数?


如果把杨辉三角画成这样,我们可以发现一个数是它上方和上方左边的和,如果在边界的话,它就是1
由此我们可以处理出前100行然后一行一行的找答案

代码如下:

#include<stdio.h>
int a[105][105];
int main()
{int t;scanf("%d",&t);for(int i=1;i<=101;i++){for(int k=1;k<=i;k++){if(k==1||k==i) a[i][k]=1; //表示在边界else  a[i][k]=a[i-1][k-1]+a[i-1][k];}}while(t--){int n;scanf("%d",&n);int num = 0;int flag = 0;for(int i=1;i<=101;i++){for(int k=1;k<=i;k++){num ++ ;if(a[i][k]==n)  //表示我们找到了答案{flag = 1;break;}}if(flag)break;}printf("%d\n",num);}return 0;
}

取石子(pro plus max 版)

题目大意:
给定 n 堆石子,两位玩家轮流操作,每次操作可以从任意一堆石子中拿走任意数量的石子(可以拿完,但不能不拿),最后无法进行操作的人视为失败。
问如果两人都采用最优策略,先手是否必胜。

这道题涉及到了位运算,代码简单但思维难度较大,证明过程水平有限,大家用心看一下

首先结论: 如果初始所有值的异或结果不为0,则先手必胜,反之必败

我们可以知道0^ 0 ^… ^ 0 ^ 0=0
然后有两个推论

当序列异或的结果不为0的时候,我们必然有种方式拿走石子使异或结果为0
当序列异或的结果为0的时候,我们无论怎么拿走石子异或结果都不会再为0

证明如下

首先当a[1] ^ a[2] ^ … ^ a[n] = x != 0 时
记x的二进制表示中最高位的1是第k位,则肯定存在一个a[i]的第k位为1(因为要使两个数异或结 果 为1,必然要有一个1)
可知a[i]^x < a[i](因为x的最高位的1在k,第k位都为1,因此异或后第k为0,比k位低的异或结果不 管是怎么样的,最终结果肯定比a[i])
因此可以把a[i]变成a[i]^x
这样结果会变成a[1] ^ a[2] ^ … ^ a[i] ^ x ^ … ^ a[n] = 0

当a[1] ^ a[2] ^ … ^ a[n]= 0 (式1)时
当从任意一堆中拿走任何数量的石子后,异或结果肯定不等于0
反证法证明:
假设从任意一堆a[i]中拿走任何数量的石子后(a[i]变成a[t]),异或结果等于0,则a[1] ^ a[2] ^ … ^ a[t] ^ … a[n] = 0(式2)
则 式1^式2 = 0 -> a[t] ^ a[i] = 0 -> a[t] = a[i] , 这与a[i] > a[t]矛盾,因此假设不成立

所以当序列异或结果不为0时,先手可以让异或结果变成0,后手只能让异或结果不为0,然后如此往复,最后一定是先手到达 0^ 0 ^… ^ 0 ^ 0=0,的状态,也就是胜利,反之,先手必败
代码如下:

#include <stdio.h>int main()
{int res=0,n=0;scanf("%d",&n);while(n--){int x;scanf("%d",&x);res ^= x;}if(res) printf("Yes");else printf("No");return 0;
}

重生之我在异世界遇到差分。

题目大意:
给你长度为n的路,每个点都有一个怪物,血量是ai,你可以对某个区间的所有怪物造成1点伤害,但是如果这个点怪物血量为0,还对这个点造成伤害的话是不允许的,问你最少进行多少次操作可以击败所有怪物。

这道题我们可以这样想,
1.如果ai>ai-1,那么答案只用加上ai-ai-1就行了,因为我们完全可以在减ai-1的血量的时候顺便再把ai算上,最后只需要多算它们两个的差就行了。
2.如果ai<=ai-1,那么答案就不用更新,因为我们在减ai-1的时候就顺带着可以把ai的血量减完了

代码如下:

#include<stdio.h>
int a[2000005];
int main(){int n,sum=0;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&a[i]);if(a[i]-a[i-1]>0) sum+=a[i]-a[i-1];}printf("%d",sum);
}

NYIST前缀和,差分,位运算训练题解相关推荐

  1. 2021牛客暑期多校训练营3 I-Kuriyama Mirai and Exclusive Or (差分+位运算)

    题意: 两个操作: 1.给区间[l,r][l,r][l,r]之间的数异或xxx 2.给区间[l,r][l,r][l,r]之间异或(x+(l−i))(x+(l-i) )(x+(l−i)) 题解: 我们发 ...

  2. LeetCode 1829. 每个查询的最大异或值(前缀异或 + 位运算)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个 有序 数组 nums ,它由 n 个非负整数组成,同时给你一个整数 maximumBit .你需要执行以下查询 n 次: 找到一个非负整数 k ...

  3. 沙之家的塔塔露有事寻求冒险者 (位运算 前缀和 差分

    添加链接描述 首先考虑位运算或的性质 可以发现当x的当前位0时则所有l~r的当前位都为0 所以要判断当前位采用差分 d[35][N] 前缀和后判断是否当前位为1则舍去 否则1<<i遍历30 ...

  4. 超简单的位运算---再也不用担心看不懂题解了

    超简单的位运算---再也不用担心看不懂题解了 写在前面 1.原码.反码与补码------整形在计算机中的储存 2.移位操作符 3.位操作符 4.小练手 写在最后 写在前面 大家好,这里是风扇的小小笔记 ...

  5. 【题解】《算法零基础100讲》(第44讲) 位运算 (位或) 入门

    文章目录 一. 概念定义 1.1 位或定义 1.2 位与定义 二. 推荐专栏 三. 相关练习 3.1 根据数字二进制下 1 的数目排序 3.2 二进制表示中质数个计算置位 3.3 2 的幂 一. 概念 ...

  6. 【NOIP2009】【DLX】【位运算】T4 靶形数独 题解

    小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向Z 博士请教,Z 博士拿出了他最近发明的"靶形 ...

  7. 11.12PTA训练 人狼羊菜过河 搜索,位运算

    题意 人不在的时候狼吃羊,羊吃菜,用MWGC表示人狼羊草,箭头代表行进方向,输出所有由初始情况到最终情况的解决方案 思路 目前为止写得最头疼的搜索 因为一岸的状态确定了,另一岸也就唯一确定了,所以可以 ...

  8. bzoj5108 [CodePlus2017]可做题 位运算dp+离散

    [CodePlus2017]可做题 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 87  Solved: 63 [Submit][Status][D ...

  9. 位运算卷积(FWT)

    本文大量参考了: command_block 的博客:位运算卷积(FWT) & 集合幂级数 FWT 概论 定义位运算卷积:C[k]=∑i⊕j=kA[i]B[j]C[k]=\sum\limits ...

最新文章

  1. EventBus的粘性事件原理
  2. 重读TCP协议(3)
  3. 玩转双核CPU:左手画圆,右手画方
  4. Photoshop简单另类方法给黑白照片上色
  5. MATLAB 图像函数(第五章) 图像空间变换和图像配准
  6. 树莓派4b设置RTC时钟模块DS3231
  7. 关于JetBrains CLion 激活 (CLion License Activation)的解决办法,带hosts详细修改
  8. Buck降压电路仿真与解析
  9. ios 开发账号 退出协作_如何在iOS 10中的Notes上进行协作
  10. CF204E-Little Elephant and Strings【广义SAM,线段树合并】
  11. flask bootstrap ajax,使用Flask集成bootstrap的方法
  12. 方维分享系统,品牌无法设置分类关联
  13. Hibernate检索方式简单总结
  14. onCreateView中加载大位图
  15. 再见了,收费的XShell,我改用国产良心工具!
  16. CVPR等会议论文集检索下载与数据库资源使用
  17. c语言解一元二次方程虚根oj,OJ 1040 Problem J 求一元二次方程的根
  18. Matlab提示Ill-conditioned covariance created at iteration
  19. php开发APP接口 接收客户端的图片
  20. 十六进制转换为ASC码

热门文章

  1. 原生js如何创建弹出层
  2. 数字化校园建设之实践二
  3. go语言的魔幻旅程03-控制结构
  4. 上传图片前限制图片比例大小格式
  5. 《流浪地球》观影心得
  6. 王济 matlab,关于王济老师《Matlab在振动信号处理中的应用》书中第八章8.3节 程序8.2a的问题...
  7. 和微信大佬聊了一夜,他告诉我为什么指针被誉为 C 语言灵魂?
  8. python查看神经网络参数大小
  9. 为啥我不关心制造企业内部信息化了
  10. C语言函数之—函数的分类