int函数

玩游戏——生成函数

谁说胖子不能爱 提交于 2020-04-06 09:31:13
题面    洛谷P4705 解析   答案显然是$\frac{\sum_{i=1}^n\sum_{j=1}^m (a_i+b_j)^k}{n*m}$   因此只需要求出$\sum_{i=1}^n\sum_{j=1}^m (a_i+b_j)^k$即可   暴力展开:$$\begin{align*}\sum_{i=1}^n\sum_{j=1}^m (a_i+b_j)^k&=\sum_{i=1}^n\sum_{j=1}^m\sum_{p=0}^k\binom{k}{p}a_i^p*b_j^{k-p}\\ &=k!\sum_{p=0}^k\sum_{i=1}^n\frac{a_i^p}{p!}\sum_{j=1}^m\frac{b_j^{k-p}}{(k-p)!}\\&=k!\sum_{p=0}^k\frac{\sum_{i=1}^na_i^p}{p!}\frac{\sum_{j=1}^mb_j^{k-p}}{(k-p)!}\end{align*}$$   现在就是要求对于任一$1\leqslant p \leqslant k$,$\sum_{i=1}^na_i^p$(求$\sum_{j=1}^mb_j^{k-p}$是类似的)   这个比较常见,我在 生成函数小结 里有写,这里直接给出结论:$$\begin{align*}F(x)&=\sum_{j=0}^{\infty}\sum_{i=1

离散数学——数论算法

百般思念 提交于 2020-04-06 06:21:56
最近在复习离散数学,这篇文章是《离散数学及其应用》第六版中第三章 算法、整数、和矩阵中涉及到的几个算法,我想了一下,光看看也起不到什么作用,于是自己动手写了一下,下面的代码都是我自己按照书上的伪代码写出来的,初步验证没什么问题,如果有什么问题就请告知我一下,谢谢! 一、十进制到任意进制数据转换   根据进制转换规则:十进制到n进制整数部分除n取余向上书写,小数部分乘n取整向下书写,实际上整数部分就是用的短除法,这个算法实际上就是贪心算法的一个实例,由于是向上书写,我们可以借助栈这种特殊的数据结构很方便的就可以实现向上书写了:       #include<iostream> #include<stack> #include<stdlib.h> std::stack<int> converson(int n,int base){   if(10==base)     exit(1);   if(base<=1)     exit(1);   std::stack<int> result;   int temp;   while(n){     temp=n%base;     result.push(temp);     n/=base;   }   return result; } int main(){   int data=241;   std::stack<int>

【CSAPP笔记】10. 代码优化

谁说我不能喝 提交于 2020-04-06 05:48:09
写程序的主要目标是使它在所有可能的情况下都能正确运行(bug free),一个运行得很快但有 bug 的程序是毫无用处的。在 bug free 的基础上,程序员必须写出清晰简洁的代码,这样做是为了今后检查代码或修改代码时,其他人能够读懂和理解代码。另一方面,让程序运行得更快也是一个很重要的考虑因素。不过,程序获得最大加速比的时候,是它第一次运行起来的时候。 在提到优化程序性能时(Code optimization),我们往往会想到算法与数据结构中的一个概念——复杂度。事实上,除了算法复杂度之外,仍然有许多的代码书写小细节可以改进性能表现。不过,编写高效的程序,第一个考虑的还是选择一组合适的算法与数据结构,因为算法复杂度影响还是相当大的,而且通常比其他常量因素更重要。第二点,我们必须写出编译器能够有效优化以转换成高效可执行代码的源代码。对于第二点,理解程序是如何被编译和执行、理解处理器和存储器系统是如何运作的、理解编译器优化的局限性是很重要的。在程序开发过程中,程序员必须在实现和维护程序的简单性与它的运行速度之间做出权衡,也就是在尽量不破坏程序的模块化和通用性的前提下,做到对代码性能的优化。 即使是最好的编译器也受到 妨碍优化的因素 (optimization blocker)的阻碍,程序员必须编写容易优化的代码,来 帮助 编译器(很让人眼界一新的观点)。研究程序的汇编代码

数据结构和算法(面试)

馋奶兔 提交于 2020-04-06 04:28:30
排序算法 直接插入排序 :将数组中的所有元素依次跟前面已经排好的元素相比较,如果选择的元素比已排序的元素小,则交换,直到全部元素都比较过 希尔排序 :将待排序数组按照步长gap进行分组,然后将每组的元素利用直接插入排序的方法进行排序;每次将gap折半减小,循环上述操作;当gap=1时,利用直接插入,完成排序 简单选择排序 :比较+交换 堆排序 :构建大顶堆进行排序 如何手写一个堆 1. 插入一个数 heap[ ++ size ] = x; up(size); 2. 邱集合当中的最小值 heap[1] 3. 删除最小值 heap[1] = heap[size]; size --; down(1); 4. 删除任意一个元素 heap[k] = heap[size]; size --; down(k); up(k); 5. 修改任意一个元素 heap[k] = x; down(k); up(k); 堆排序 int n, m; int h[ 1000 ], cnt; void down( int u ) { int t = u; if( u * 2 <= cnt && h[ u * 2 ] < h[ t ] ) t = u * 2; if( u * 2 + 1 <= cnt && h[ u * 2 + 1 ] < h[ t ] ) t = u * 2 + 1; if( u != t ) {

四种排序算法

▼魔方 西西 提交于 2020-04-06 03:57:24
前言:经过昨天做的排序算法题,发现自己这么简单的题都忘记怎么做了,感觉很难受,今天复习整理了一遍,写成一个文章,以便日后复习,其中冒泡、选择、插入三种算法的思路和图片来自于B站up主"正月点灯笼",感谢你的讲解,我觉得你讲的非常好! 冒泡排序 例如 3、7、4、2、6、1这一个数组,我们对它进行升序的一个排序 1、首先从左往右两两进行比较,若左>右,则交换位置,进行第一趟排序 对于这第一趟的排序,并不能保证从左往右一定都是正确的升序排序,但是一定能保证最大的数已经排在了最右边 由此,我们可以得到一个思路,在第一趟排序后,我们只需要对这个长度为6的数组左边5个数字再进行一次冒泡排序,然后再对左边4个数字再进行一次冒泡排序,以此类推..... #include <stdio.h> /* 冒泡排序算法 */ /*** * @Description:交换函数,交换括号内的参数 * [@Param](https://my.oschina.net/u/2303379): &a,&b * [@return](https://my.oschina.net/u/556800): * [@Author](https://my.oschina.net/arthor): JaneRoad * [@Date](https://my.oschina.net/u/2504391): 2020/4/1 */

高效率的object转int的函数

人走茶凉 提交于 2020-04-06 01:50:44
在通常情况,object转int都会使用.net framework的Convert.ToInt32或者Int32.Parse()函数,但这不是最高效的方式,下面的两个方案不错 MS给出的答案: public static ToInt32(object value) { if(value != null) { return ((IConvertible)value).ToInt32(null); } return 0; } 这种做法很OO,很优雅,但不能转换像"123.4"这样的数字字符,有一定缺陷; 另外一种是CSDN上的一位高手提供的: static int ToInt(object o) { if (o is int) return (int)o; else if (o is short) return (int)(short)o; else if (o is byte) return (int)(byte)o; else if (o is long) return (int)(long)o; else if (o is double) return (int)(double)o; else if (o is float) return (int)(float)o; else if (o is decimal) return (int)(decimal)o; else if

引用

生来就可爱ヽ(ⅴ<●) 提交于 2020-04-05 19:41:15
引用是指针的延申,本质相同但是引用的写法和可阅读性更强。 引用是引用一个已经存在的变量,而指针可以新建一个不存在的新指针 #include<iostream> #define Log(x) std::cout<<x<<std::endl int main() { int a=5; int *b=&a; int& ref=a; ref=2; Log(a); std::cin.get(); } 引用时int和&是一个整体表示引用类型,引用并不会申请内存空间,引用相当于给变量起了一个别名。所以上面程序对ref操作也就相当于对a操作。常见错误是在引用函数时,经过函数运算后值并没有变。 #include<iostream> #define Log(x) std::cout<<x<<std::endl void Increment(int value) { value++; } int main() { int a=5; Increment(a); Log(a); std::cin.get(); } 如果想通过函数Increment改变a的值,那么有两种方法,一是将a的地址传入函数,二是使用引用 使用指针 #include<iostream> #define Log(x) std::cout<<x<<std::endl void Increment(int *value) { (*value)

Runtime Error可能的情况

烈酒焚心 提交于 2020-04-05 19:13:27
runtime error (运行时错误)其本意就是就是程序运行到一半,程序就崩溃了。 在oj上做题提交时出现RE可能有以下几个原因: 1.除以了0 。 2.数组越界:比如int a[8]; 却访问了使其a[100000]=9;,只能开大数组。 3.指针越界:比如int * p; p=(int *)malloc(10 * sizeof(int)); *(p+10000)=10;,需要重新申请空间。 4.使用已经释放的空间:如int * p; p=(int *)malloc(10 * sizeof(int));free(p); *p=10;,使用时注意仔细。 5.数组开得太大,超出了栈的范围,造成栈溢出:比如在主函数或用户函数种将数组开至a[100000000],函数内部(局部数组)承载不了这么大范围的数组,但是将其设置为全局变量可以避免。 6.还有可能是函数递归的时候传参时不正确(比如大小关系),导致递归溢出所定义范围。 当有提示信息时,分别对应以下: 1.Runtime Error(ARRAY_BOUNDS_EXCEEDED) // array bounds exceed 数组越界(错误1) 2.Runtime Error(DIVIDE_BY_ZERO) //divisor is nil 除以0 3.Runtime Error(ACCESS_VIOLATION) /

LOJ #573. 「LibreOJ NOI Round #2」单枪匹马 线段树

白昼怎懂夜的黑 提交于 2020-04-05 15:33:21
$f$ 函数暴力计算的话是 $O(n)$ 的(用一个 $\frac{x}{y}$ 来保存每一步计算结果,然后依次合并) 我们将一段区间的结果写成 $\frac{ax+by}{cx+dy}$ 的形式,初始时 $(x=0,y=1)$,然后这样的话就可以将区间分治,然后左右区间合并了. 注意合并的时候要把右区间的分子和分母调换一下. code: #include <bits/stdc++.h> #define N 1000007 #define mod 998244353 #define ll long long #define lson now<<1 #define rson now<<1|1 #define setIO(s) freopen(s".in","r",stdin) ,freopen(s".out","w",stdout) using namespace std; char *p1,*p2,buf[100000]; #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++) int rd() {int x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc();

SIR单个节点作为传播源

Deadly 提交于 2020-04-04 13:15:20
void SIR(ALGraph* G,int a,double inf,double rec,char* str) //传入的分别为网络,感染节点,感染率,恢复率,写入的文件 { double rate;//传入节点作为感染节点的感染规模 int infTatal=1;//感染节点总数 int Inf[G->vexnum]; int newInf[G->vexnum]; int i=0; FILE* fp; fp=fopen(str,"at"); //给感染数组赋初值 for(i=0;i<infTatal;i++) { Inf[i]=a; G->adjlist[i].nodeState=0;//传入的数组为感染态 } for(i=0;i<infTatal;i++) { newInf[i]=0; } double infection=inf;//感染概率 int count=infTatal;//当前网络中的感染个数 srand((unsigned)time(NULL)); //设置种子,用于随机数产生 while(count>0)//还能继续感染 { int newInfLength=0;//表示新感染节点的个数 for(i=0;i<count;i++) { int vert=Inf[i];//当前的感染点 EdgeNode* p; p=G->adjlist[vert]