学大伟业 Day 1 培训总结

第一天培训,讲的基本算法,东西很多。还有些数论,图论,数据结构and some small tricks

 

一.输入输出技巧

 1 //输入输出技巧
 2 /*
 3 scanf、printf:速度快,需要记忆不同数据类型的格式化字符串
 4 cin、cout:简单,在某些情况下较慢
 5 getchar:读入一个字符
 6 puts/gets/cin.getline(a,100)如果a是大小为100的字符数组/getline(cin,a)如果a是一个string:输出/输入一个字符串
 7 */ 
 8 #include<iostream>
 9 #include<cstdio>
10 #include<cstring>
11 #include<algorithm>
12 using namespace std;
13 int main()
14 {   int a,n,h,min;
15     char m[3]; 
16     // 1.题目中不清楚输入输出的数据数量,可以用scanf的返回值解决。 
17     while(scanf("%d",&a)!=EOF)
18     {   
19         n++;
20         //.....
21     } 
22     // 2.cin读入字符串以空格、回车结束。scanf、getchar读入字符串不会舍弃回车。gets读入字符串以回车结束。 
23     std::ios::sync_with_stdio(false);//cin可以关闭同步加速。 
24 
25     // 3.scanf的妙用。举个栗子。再输入一个时间的时候,往往用字符串读入再取出时间。但scanf可以直接取出时间。 
26     scanf("%d:%d",&h,&min);//当在读入时必须遇到‘:’才会继续读入,读入的为两个整数,就是时间。  
27 } 

二.数组的高级用法

 1 //基础数据结构——数组
 2 /*
 3 数组很常见,同时也是很多高级数据结构的基础
 4 数组也有很多妙用
 5 
 6 基本:储存数据,做统计等
 7 扩展:部分和数组,差分数组
 8 */ 
 9 #include<iostream>
10 #include<cstdio>
11 #include<algorithm>
12 #include<cstring>
13 using namespace std;
14 int a[100];
15 int sum[100];//部分和(前缀和)数组 sum[i]表示 a[i]+a[2]+...+a[i] 的值 
16 int diff[100];//差分数组 
17 int sumd[100];//差分数组diff的部分和数组 
18 int main()
19 {   
20     int n;
21     scanf("%d",&n);
22     for(int i=1;i<=n;i++)
23     scanf("%d",&a[i]);
24 
25     //sum :
26      sum[1]=a[1];
27      for(int i=2;i<=n;i++)
28      sum[i]=sum[i-1]+a[i];
29     //用途:方便计算区间 L~R 的值num
30     int L,R;
31     scanf("%d%d",&L,&R); 
32     int num=sum[R]-sum[L-1];
33 
34     //diff :
35      diff[1]=a[1];
36      for(int i=2;i<=n;i++)
37      diff[i]=a[i]-a[i-1];
38     //用途:差分数组适用于离线的区间修改问题   
39     //常用结论:a[]的差分数组是diff[]  而diff[]的部分和数组是a[] 
40 /*证明:sumd[i]=diff[1]+diff[2]+...+diff[i]
41                                                     sumd[i]=a[1]+a[2]-a[1]+a[3]-a[2]+...+a[i]-a[i-1]=a[i]*/ 
42 }

三.竞赛树

 1 //竞赛树
 2 /*
 3 针对添加元素的数量确定的情况
 4 使用多一倍的空间,换取代码实现上的方便
 5 关键操作:上滤
 6 一种很奇怪的数据结构..也不算奇怪总之做题时会有用处的。
 7 数据都储存在叶子节点,内部节点储存子节点的较大值。 
 8 */ 
 9 #include<iostream>
10 using namespace std;
11 const int INF = 0x7fffffff/2;
12 const int MAXN = 5001;
13 struct tree{
14     int data[MAXN*2];
15     int n;
16     tree(int n)
17     {
18         this->n=n;
19         for(int i=1;i<=2*n-1;i++) data[i]=-INF;
20     }
21     void update(int pos, int value)
22     {
23         pos=pos+n-1;
24         data[pos]=value;
25         while(pos/=2) data[pos]=max(data[pos*2],data[pos*2+1]);
26     }
27     int top() { return data[1];}//返回最大值 
28     int toppos()//返回最大值的位置 
29     {
30         int pos=1;
31         while(pos<n)
32         {
33             if(data[pos]==data[pos*2]) pos=pos*2;
34             else pos=pos*2+1;
35         }
36         return pos-n+1;
37     } 
38 };
39 int main()
40 {
41     //.....
42 } 

四.快速幂

 1 //数论——快速幂
 2 /*
 3 计算 k^p%m 
 4 递归的版本(并不如位运算效率高),运算时采用乘法。
 5 其实可以改成加法,使用加法更不容易爆longlong.
 6 */ 
 7 #include<iostream> 
 8 #include<cstdio>
 9 using namespace std;
10 int pow1(int k,int p,int m)
11 {
12     if(p == 0) return 1;
13     long long ans = pow1(k,p/2,m);
14     return p%2==1?(ans*ans*k)%m:(ans*ans)%m;
15 }
16 long long pow2(long long k,long long p,long long m)
17 {
18     if(p==0) return 1;
19     long long ans=pow2(k,p/2,m);
20     return p%2==1?(ans+k)%m:(ans+ans)%m;
21 } 
22 int main()
23 {
24     long long k,p,m;
25     cin>>k>>p>>m;
26     cout<<k<<"^"<<p<<" mod "<<m<<"="<<pow2(k,p,m);
27     cout<<k<<"^"<<p<<" mod "<<m<<"="<<pow1(k,p,m);
28     return 0; 
29 }

 

posted @ 2018-02-25 18:43  Misaka_Azusa  阅读(299)  评论(0编辑  收藏  举报
Live2D