码迷,mamicode.com
首页 > 其他好文 > 详细

五一清北总结——day1+day2

时间:2018-05-08 22:27:49      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:return   cst   sort   二分   冒泡   利用   总结   避免   树状   

                                五一清北学习总结

                                      ——day1+day2

一、排序

1.快速排序

O(nlogn)的排序,用sort可以快速完成,但是可以被卡,手写sort利用随机数可以避免被卡掉。

代码:

void quick_sort(int *a, int l, int r)

{

swap(a[l], a[rand()*rand() % (r -l + 1) +l]);

int tmp = a[l];

int l_ = l, r_ = r;

while (l < r)

{

while (l < r)

{

if (a[r] > tmp) r--; //a[r]落在正确的位置

else

{

a[l] = a[r];

l++;

break;

}

}

while (l < r)

{

if (a[l] < tmp) l++; //a[l]落在正确的位置

else

{

a[r] = a[l];

r--;

break;

}

}

}

a[l] = tmp;

if (l - l_ > 1) quick_sort(a, l_, l - 1);

if (r_ - r > 1) quick_sort(a, r + 1, r_);

}

2.冒泡排序

每次选出一个最大值或最小值放在正确的位置,进行n-1次循环,然后就得到了一个有序序列。复杂度O(n2),一般不使用。

代码:

void bubble_sort(int *a, int l, int r, int n)

{

for (int i = 1; i < n; i++)

{

for (int j = l; j < r; j++)

{

if (a[j] > a[j + 1]) swap(a[j], a[j + 1]);

}

}

}

3.归并排序

采用分治的方法,达到O(nlogn)排序的方法,采用递归实现,可以用来找逆序对。

代码:

void merge_sort(int *a, int l, int r)

{

if (l == r) return;

int mid = (l + r) >> 1;

merge_sort(a, l, mid);

merge_sort(a, mid + 1, r);

 

int i = l, j = mid + 1;

//b:辅助数组

for (int k = l; k <= r; k++)

{

if (j > r || (i <= mid && a[i] < a[j]))

{

b[k] = a[i];

i++;

ans += j - (mid + 1);

}

else

{

b[k] = a[j];

j++;

}

}

for (int k = l; k <= r; k++)

a[k] =b[k];

}

 

4.插入排序

在线排序算法,每插入一个元素将其与前一个元素比较,如果位置不对,就将其交换,知道到达正确位置。

5.堆排序

利用二叉树实现的一种排序,可以用stl里的优先队列实现。

二、快速幂

采用二分的思想,将一个求幂的式子的幂进行不断除以二,然后降低复杂度,快速幂的思想可以运用于所有a*b的运算,其中*代表任意一种运算符。例如快速乘法,快速乘法并不比普通的乘法快,但是它可以完成较大数相乘,对一个数取模的情况,因为他可以一边乘一边模。

代码:

lude<cstdio>

#include<iostream>

using namespace std;

int fpow(int a,int x)

{

int ans=1;

for(int now=a;x;x>>=1,now=now*now)

{

if(x&1) ans=ans*now;

}

return ans;

}

int cf(int a,int x,int mo)

{

int ans=o;

for(int now=a;x;x>>=1,now=(now+now)%mo)

if(x&1) ans=(ans+now)%mo;

return ans;

}

int main()

{

int a,x,mo;

scanf("%d%d",&a,&x);

printf("%d",fpow(a,x));

printf("%d",cf(a,x,mo));

return 0;

}

三、高精

用于大整数运算,将其包装在结构体里方便使用。

代码:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<cmath>

#include<cstdlib>

#include<ctime>

#include<string>

using namespace std;

 

 

 

struct bignum

{

int n;

int a[500];

bignum()

{

n = 0;

memset(a, 0, sizeof(a));

}

 

bignum(string s)

{

n = s.size();

memset(a, 0, sizeof(a));

for (int i = 0; i < n; i++)

a[i] = s[n - 1 -i] -‘0‘;

}

bignum(int s)

{

memset(a, 0, sizeof(a));

n = 0;

while (s > 0)

{

a[n] = s % 10;

s /= 10;

n++;

}

}

void work()

{

for (int i = 0; i < n; i++)

{

if (a[i] < 0)

{

int tmp = (-a[i] - 1) / 10 + 1;

a[i] += 10 * tmp;

a[i + 1] -= tmp;

}

if (a[i] >= 10)

{

int tmp = a[i] / 10;

a[i] -= 10* tmp;

a[i + 1] += tmp;

if (i == n - 1 && a[i + 1] > 0) n++;

}

}

while (n > 0 && a[n - 1] == 0) n--;

}

void print()

{

for (int i = n - 1; i >= 0; i--)

cout << a[i];

cout << endl;

}

};

 

bignum operator + (const bignum &a, const bignum &b)

{

bignum c;

c.n = max(a.n, b.n);

for (int i = 0; i < c.n; i++)

c.a[i] = a.a[i] + b.a[i];

c.work();

return c;

}

 

 

bignum operator - (const bignum &a, const bignum &b)

{

bignum c;

c.n = max(a.n, b.n);

for (int i = 0; i < c.n; i++)

c.a[i] = a.a[i] - b.a[i];

c.work();

return c;

}

 

 

bignum operator * (const bignum &a, const bignum &b)

{

bignum c;

c.n = a.n + b.n - 1;

for (int i = 0; i < a.n; i++)

for (int j = 0; j < b.n; j++)

c.a[i + j] += a.a[i] * b.a[j];

c.work();

return c;

}

 

 

int main()

{

string s;

cin >> s;

int x;

cin >> x;

bignum a(s);

bignum b(x);

(a + b).print();

(a - b).print();

(a * b).print();

return 0;

}

四、二分

可以降低复杂度,需要找到单调性,然后根据单调性对要二分的数进行二分,然后将二分到的数进行check,知道找到正确答案或者达到一定精度。

采用二分的题目中常常蕴含着最大值最小或者最小值最大的信息。

如果想不清楚在循环里是应该取l=mid+1还是r=mid-1那么就可以再循环外面在进行一次check

五、前缀和数组与差分数组

前缀和数组用来记录前i个数字之和,差分数组则是储存当前数与前一个元素之差。

对于前缀和数组与差分数组有:前缀和数组的差分数组是原数组,差分数组的前缀和数组是原数组。

对于差分数组有:当一个区间同时加或减同一个数时,对于该序列的差分数组,只需将区间首元素位置加或减这个数,区间尾元素的下一个位置进行相反处理。

利用这两个性质,可以完成树状数组的区间修改与单点查询。

五一清北总结——day1+day2

标签:return   cst   sort   二分   冒泡   利用   总结   避免   树状   

原文地址:https://www.cnblogs.com/wxyww/p/9010967.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!