NOIP常用模板(随便整理的,很杂)

输入挂:

inline int Read()
{
    register int sign=1,v=0; register char ch;
    while (!isdigit(ch=getchar())) if (ch=='-') break;
    if (ch=='-') sign=-1; else v=ch-48;
    while (isdigit(ch=getchar())) v=v*10+ch-48;
    if(sign==1) return v; else return -v;
}

当输入中既含数字与字符的时候时慎用,因为换行符的原因会产生紊乱(Windows下的\n\r,占两个字符所致,如果是Linux生成的数据只有\n则不会产生误差)
输出挂:

void myout(int a){
	if(a<0) putchar('-'),a=-a;
	if(a>=10) myout(a/10);
	putchar(a%10+'0');
}

亲测提升并不多,但也有100ms左右(100W输出量)。

关闭流同步:
【如果要关闭流同步就一定不能使用scanf与printf!!!(因为极有可能会产生输入输出不完整或者顺序错乱的情况)】

ios::sync_with_stdio(false);
cin.tie(0);

只有优化cin读入的效果,并不能够优化输出(要优化输出须使用输出挂)
模下的基本运算:

void inc(int &a, int b) { if ((a += b) >= MOD) a -= MOD; }
int add(int a, int b) { if ((a += b) >= MOD) a -= MOD; return a; }
int mul(int a, int b) { return ll(a) * b % MOD; }

优先队列:

priority_queue< int,vector<int>,greater<int> > qs;
//优先队列默认是大根堆,使用greater变成小根堆

位运算:

1.求二进制表示中a有多少个1while(a) cnt++,a&=(a-1);
2.求二进制表示中a有多少个0while(a) cnt++,a|=(a+1);
3.二进制表示中a最低位的一个1的位置(自低位向高位)为i,求2^i:
	a=a&(-a);(就是树状数组里面的那一个lowbit)

离散化:

void lisanhua(int x[]){//首先c++调用一个数组直接打这个数组的类型就好了。
    数据类型 data[数据规模];
    for(i,1,n)data[i]=x[i];
    sort(data+1,data+1+n);//排序
    int o=unique(data+1,data+1+n)-data-1;//对data数组[1..n]进行去重
    for(i,1,n)x[i]=lower_bound(data+1,data+1+o,x[i])-data;//找到x[i]在data中的位置再赋值为这个位置,如果不减去data就是返回这个值。
}

对拍DOS程序:(写在.dos文件里)

@echo off (取消多余信息的显示)
:loop (循环的标记)
DataGenerator.exe %random% > data.in (运行数据生成器)
a.exe < data.in > a.out 
b.exe < data.in > b.out
fc a.out b.out
if not errorlevel 1 goto loop
pause
goto loop

随机数生成:

#include<bits/stdc++.h>
using namespace std;
#define random(a,b) ((a)+rand()%((b)-(a)+1))
stringstream ss;
int main( int argc, char *argv[] )
{ 
    int seed=time(NULL);
    if(argc > 1)//如果有参数
    {
        ss.clear();
        ss<<argv[1];
        ss>>seed;//把参数转换成整数赋值给seed
    }
    srand(seed);
    //以上为随机数初始化,请勿修改
    //random(a,b)生成[a,b]的随机整数

    //以下写你自己的数据生成代码 
    int a=random(1,1000000),b=random(1,1000000);
    printf("%d %d\n",a,b);
    return 0;
}

时间及运行时长获取:(用来卡时间,例如时限1秒,复杂度会超时的暴力运行到900多毫秒的时候就停止进行,输出当前的最优答案。)
【据说NOIP不能使用windows.h头文件】

#include<windows.h>
unsigned int start_time=GetTickCount();
·····核心代码
unsigned int end_time=GetTickCount();
cout<<end_time-start_time<<"ms";

初始化:

无穷大:
 memset(a,0x7f,sizeof(a));//二十一亿,接近int最大值,缺点是两个无穷大相加会溢出
 0x7f等同于127
 memset(a,0x3f,sizeof(a));//十亿多一点,没有0x7f大,但是两个无穷大相加不会溢
 出。
无穷小:
 memset(a,0x80,sizeof(a));//接近int最小值。
 0x80等同于128

进制转换:

    cin>>a;
    cout<<dec<<a<<endl;//dec,十进制输出
    cout<<hex<<a<<endl;//hex,十六进制输出
    cout<<oct<<a<<endl;//oct,八进制输出

矩阵乘法及快速幂

struct Mat{
	ll a[N+1][N+1];
	Mat(){ memset(a,0,sizeof(a)); }//默认构造函数,初始化为空。
	Mat(ll x){//单位矩阵构造函数,初始化为单位矩阵。
		memset(a,0,sizeof(a));
		rep(i,1,N) a[i][i]=x;
	}
	Mat friend operator * (Mat a, Mat b){
		Mat ret;
		rep(i,1,N) rep(j,1,N) rep(k,1,N) ret.a[i][j]=(ret.a[i][j]+a.a[i][k]*b.a[k][j])%m;
		return ret; 
	}
};

//矩阵快速幂
Mat ksm(Mat a,int b){
	Mat ret(1);//单位矩阵,相当于‘1’的作用。
	while(b){
		if(b&1) ret=ret*a;
		a=a*a;
		b>>=1;
	}
	return ret;
}

二元组及向量运算(数乘、求模、点积、叉积及求夹角等)

struct P
{
    double x,y; 
    P(){}//无参构造函数 (默认构造函数,若无,则数组无法自动初始化,报错。)
    P(double _x,double _y) {x=_x; y=_y;}
}A[Maxn],B[Maxn];
P operator + (P A,P B) {return P(A.x+B.x,A.y+B.y);}
P operator - (P A,P B) {return P(A.x-B.x,A.y-B.y);}
P operator * (P A,double rhs) {return P(A.x*rhs,A.y*rhs);}
P operator / (P A,double rhs) {return P(A.x/rhs,A.y/rhs);}
int dcmp(double x) {if (fabs(x)<eps) return 0; else return x<0?-1:1;}
bool operator == (const P& A,const P &B){return dcmp(A.x-B.x)==0 && dcmp(A.y-B.y)==0;}
 
bool cmp_ConveHull(P a,P b) {return a.x<b.x||(a.x==b.x && a.y<b.y);}
struct Vec
{
    double Dot(P A,P B) {return A.x*B.x+A.y*B.y;}
    double Len(P A) {return sqrt(Dot(A,A));}
    double Angle(P A,P B) {return acos(Dot(A,B)/Len(A)/Len(B));}
    double Cross(P A,P B) {return A.x*B.y-A.y*B.x;}
 
    bool SegmenttoSegment(P a1,P a2, P b1, P b2)
    {
        double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1),
               c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1);
        return dcmp(c1)*dcmp(c2)<=0 && dcmp(c3)*dcmp(c4)<=0;
    }
};

觉得有用的话,请点个赞让我知道一下吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值