NOIP模板总结

NOIP模板总结

  进考场先打一份缺省源:

  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 int main()
13 {
14 
15     return 0;
16 }
缺省源

调配置:

  ·工具->编译选项->代码警告->显示最多警告消息;

  ·工具->编译选项->连接器->产生调试信息;

  ·(如果$IDE$右边有奇怪的白色竖线):工具->编辑器属性->基本->右边缘->把勾去掉;

  ·工具->编辑器属性->高亮显示当前行->$Green$;

  ·工具->编辑器属性->显示->字体:$Andalus$->大小$10$;

  ·工具->编辑器属性->语法->预设$Obsidian$;

  虽然比不上$Vscode$漂亮,但是至少挺清楚的.

  本来想把数据结构都封装成结构体,后来发现没什么用处还容易错...等联赛完了再弄这些东西吧。

  

dp优化:

  注意矩阵乘法时一定要把$k$写在最外层循环,因为每次访问的内存连续所以可以快很多,真的快很多!

  
 1 struct mat
 2 {
 3     int n,m;
 4     ll a[maxn][maxn];
 5     void init()
 6     {
 7         memset(a,0,sizeof(a));
 8         for (R i=0;i<5;++i)
 9             a[i][i]=1;
10     }
11     void cler() { memset(a,0,sizeof(a)); }
12     mat operator *  (const mat &a) const
13     {
14         mat c;
15         c.cler();
16         for (R k=0;k<a.m;++k)
17             for (R i=0;i<this->n;++i)
18                 for (R j=0;j<this->m;++j)    
19                     c.a[i][j]=(c.a[i][j]+this->a[i][k]*a.a[k][j]%m)%m;
20         c.n=n;
21         c.m=a.m;
22         return c;
23     }
24 };
25 
26 mat qui (mat a,int p)
27 {
28     mat ans;
29     ans.init();
30     ans.n=ans.m=5;
31     while(p)
32     {
33         if(p&1) ans=ans*a;
34         a=a*a;
35         p>>=1;
36     }
37     return ans;
38 }
矩阵快速幂
  
 1 ll X (int i) { return ; }
 2 ll Y (int i) { return ; }
 3 ll K (int i) { return ; }
 4 ll B (int i) { return ; }
 5 double KK (int a,int b) {    if(X(b)==X(a)) return 0; return (double)(Y(b,j)-Y(a,j))/(X(b)-X(a));    }
 6 
 7 struct xq
 8 {
 9     int q[maxn];
10     int h,t;
11     void ins (int i)
12     {
13         int a,b,c;
14         if(h<t) a=q[t-1],b=q[t],c=i;
15         while(h<t&&KK(a,b)>KK(a,c))
16         {
17             t--;
18             if(h<t) a=q[t-1],b=q[t],c=i;
19         }
20         q[++t]=i;
21     }
22     void del (int i)
23     {
24         int a,b;
25         if(h<t) a=q[h],b=q[h+1];
26         while(h<t&&KK(a,b)<K(i))
27         {
28             h++;
29             if(h<t) a=q[h],b=q[h+1];    
30         }    
31     }
32     void init() { h=1,t=0; }
33     int firs () { return q[h]; }
34 }q;
基于单调队列的斜率优化

数论算法:

  
1 int gcd (int a,int b) { return b?gcd(b,a%b):a; }
gcd
  
 1 int gcd (int a,int b)
 2 {
 3     int p=1;
 4     if(a<b) swap(a,b);
 5     while(a&&b)
 6     {
 7         if(a%2==0&&b%2==0) p*=2,a/=2,b/=2;
 8         else if(a%2&&b%2==0) b/=2;
 9         else if(a%2==0&&b%2) a/=2;
10         else a-=b;
11         if(a<b) swap(a,b);
12     }
13     return p*a;
14 }
Stein算法求gcd
  
  1 # include <cstdio>
  2 # include <iostream>
  3 # include <cstring>
  4 # include <string>
  5 # define R register int
  6 
  7 using namespace std;
  8 
  9 const int maxn=10005;
 10 const int base=1e8;
 11 char c[maxn];
 12 struct big
 13 {
 14     int a[maxn];
 15     int len;
 16     void write()
 17     {
 18         printf("%d",a[len]);
 19         for (R i=len-1;i>=1;--i)
 20             printf("%08d",a[i]);
 21         if(len==0) printf("0");
 22     }
 23     void div()
 24     {
 25         int mod=0;
 26         for (R i=len;i>=1;--i)
 27         {
 28             a[i]+=mod*base;
 29             mod=a[i]%2;
 30             a[i]/=2;
 31         }
 32         while (a[ len ]==0&&len) len--;
 33     }
 34     void clear()
 35     {
 36         memset(a,0,sizeof(a));
 37         len=0;
 38     }
 39     void mul()
 40     {
 41         for (R i=1;i<=len;++i)
 42             a[i]*=2;
 43         for (R i=1;i<=len+1;++i)
 44             a[i+1]+=a[i]/base,a[i]%=base;
 45         len++;
 46         while (a[ len ]==0&&len) len--;
 47     }
 48     bool operator < (const big &b) const
 49     {
 50         if(b.len!=len) return len<b.len;
 51         for (R i=len;i>=1;--i)
 52             if(b.a[i]==a[i]) continue;
 53             else return a[i]<b.a[i];
 54         return false;
 55     }
 56     void read()
 57     {
 58         scanf("%s",c+1);
 59         int l=strlen(c+1);
 60         len=l/8+((l%8)?1:0);
 61         int x=0,pos=0;
 62         for (R i=1;i<=l;++i)
 63         {
 64             x=x*10+c[i]-'0';
 65             if(i%8==l%8)
 66             {
 67                 a[ len-pos ]=x;
 68                 pos++;
 69                 x=0;
 70             }
 71         }
 72         if(x) a[len-pos]=x;
 73     }
 74 }A,B;
 75 
 76 void sub()
 77 {
 78     for (R i=1;i<=B.len;++i)
 79     {
 80         A.a[i]-=B.a[i];
 81         if(A.a[i]<0) A.a[i]+=base,A.a[i+1]--;
 82     }
 83     while (A.a[ A.len ]==0&&A.len) A.len--;
 84 }
 85 
 86 void gcd ()
 87 {
 88     int cnt=0;
 89     if(A<B) swap(A,B);
 90     while (A.len&&B.len)
 91     {
 92         if(A.a[1]%2==0&&B.a[1]%2==0) cnt++,A.div(),B.div();
 93         else if (A.a[1]%2&&B.a[1]%2==0) B.div();
 94         else if (A.a[1]%2==0&&B.a[1]%2) A.div();
 95         else sub();
 96         if(A<B) swap(A,B);
 97     }
 98     for (R i=1;i<=cnt;++i)
 99         A.mul();
100     A.write();
101 }
102 
103 int main()
104 {
105     A.read();
106     B.read();
107        gcd();
108     return 0;
109 }
压位高精实现Stein算法
  
 1 void exgcd (int a,int b,int &x,int &y)
 2 {
 3     if(b==0)
 4     {
 5         x=1,y=0;
 6         return;
 7     }
 8     exgcd(b,a%b,y,x);
 9     y-=a/b*x;
10 }
exgcd
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # define R register int
 6 # define ll long long
 7 
 8 using namespace std;
 9 
10 const int maxn=10000;
11 int a[maxn],b[maxn];
12 char c[maxn];
13 
14 int main()
15 {
16     scanf("%s",c+1);
17     a[0]=strlen(c+1);
18     for (R i=1;i<=a[0];++i)
19         a[i]=c[ a[0]-i+1 ]-'0';
20     scanf("%s",c+1);
21     b[0]=strlen(c+1);
22     for (R i=1;i<=b[0];++i)
23         b[i]=c[ b[0]-i+1 ]-'0';
24     a[0]=max(a[0],b[0])+1;
25     for (R i=1;i<=a[0];++i)
26     {
27         a[i]+=b[i];
28         a[i+1]+=a[i]/10;
29         a[i]%=10;
30     }
31     while(a[ a[0] ]==0&&a[0]) a[0]--;
32     for (R i=a[0];i>=1;--i)
33         printf("%d",a[i]);
34     if(a[0]==0) printf("0");
35     return 0;
36 }
高精度加法
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # define R register int
 6 # define ll long long
 7 
 8 using namespace std;
 9 
10 const int maxn=10005;
11 int a[maxn],b[maxn];
12 char c[maxn];
13 
14 bool smaller ()
15 {
16     if(a[0]!=b[0]) return a[0]<b[0];
17     for (R i=a[0];i>=1;--i)
18         if(a[i]!=b[i]) return a[i]<b[i];
19     return false;
20 }
21 
22 void chan()
23 {
24     int n=max(a[0],b[0]);
25     for (R i=0;i<=n;++i)
26         swap(a[i],b[i]);
27 }
28 
29 int main()
30 {
31     scanf("%s",c+1);
32     a[0]=strlen(c+1);
33     for (R i=1;i<=a[0];++i)
34         a[i]=c[ a[0]-i+1 ]-'0';
35     scanf("%s",c+1);
36     b[0]=strlen(c+1);
37     for (R i=1;i<=b[0];++i)
38         b[i]=c[ b[0]-i+1 ]-'0';
39     if(smaller())
40     {
41         printf("-");
42         chan();
43     } 
44     for (R i=1;i<=a[0];++i)
45     {  
46         a[i]-=b[i];
47         if(a[i]<0) a[i]+=10,a[i+1]--;
48     }
49     while(a[ a[0] ]==0&&a[0]) a[0]--;
50     for (R i=a[0];i>=1;--i)
51         printf("%d",a[i]);
52     if(a[0]==0) printf("0");
53     return 0;
54 }
高精度减法
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # define R register int
 6 # define ll long long
 7 
 8 using namespace std;
 9 
10 const int maxn=10005;
11 int a[maxn],b[maxn],d[maxn];
12 char c[maxn];
13 
14 int main()
15 {
16     scanf("%s",c+1);
17     a[0]=strlen(c+1);
18     for (R i=1;i<=a[0];++i)
19         a[i]=c[ a[0]-i+1 ]-'0';
20     scanf("%s",c+1);
21     b[0]=strlen(c+1);
22     for (R i=1;i<=b[0];++i)
23         b[i]=c[ b[0]-i+1 ]-'0';
24     d[0]=a[0]+b[0]+2;
25     for (R i=1;i<=a[0];++i)
26         for (R j=1;j<=b[0];++j)
27             d[i+j-1]+=a[i]*b[j];
28     for (R i=1;i<=d[0];++i)
29     {
30         d[i+1]+=d[i]/10;
31         d[i]%=10;
32     }
33     while(d[ d[0] ]==0&&d[0]) d[0]--;
34     for (R i=d[0];i>=1;--i)
35         printf("%d",d[i]);
36     if(d[0]==0) printf("0");
37     return 0;
38 }
高精度乘法
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # define R register int
 6 # define ll long long
 7 
 8 using namespace std;
 9 
10 const int maxn=10005;
11 int a[maxn],b;
12 char c[maxn];
13 
14 int main()
15 {
16     scanf("%s",c+1);
17     a[0]=strlen(c+1);
18     for (R i=1;i<=a[0];++i)
19         a[i]=c[ a[0]-i+1 ]-'0';
20     scanf("%d",&b);
21     ll r=0;
22     for (R i=a[0];i>=1;--i)
23     {
24         a[i]+=r*10;
25         r=a[i]%b;
26         a[i]/=b;
27     }
28     while(a[ a[0] ]==0&&a[0]) a[0]--;
29     for (R i=a[0];i>=1;--i)
30         printf("%d",a[i]);
31     if(a[0]==0) printf("0");
32     return 0;
33 }
高精除单精

建议:

  1.每道题做完后可以开着$O_2$测一下,可能能查出来一些内存方面或者是局部变量忘记清零这样的错误.

  2.多组数据的题一定要记得清空数组,可以把所有定义的数组都先清空再看那些是不必要的,定义了$STL$的队列一定要用$q.pop()$清空,千万不要用$q.front()$.所有的变量也都要清为初始状态,注意初始状态不一定是$0$!

猜你喜欢

转载自www.cnblogs.com/shzr/p/9890352.html