ACM防卡常模板

之前卡常基本都是乘法改为加法,位运算,去绑定(sync_with_stdio),为0不运算,判断用if(aa)而不是if(aa == true)等

卡常是门学问。。(出卡常的都是畜生啊!!!)

总结了一些防卡常的基本模板

以下的都是学习了自由oj的大佬总结的

//并查集  参考1003
#include <bits/stdc++.h>
#define mset(a,b) memset(a,b,sizeof a)
#define mcpy(a,b) memcpy(a,b,sizeof b)
#define max(a,b) ((a)<(b)?(b):(a))
#define min(a,b) ((a)<(b)?(a):(b))
#define swap(a,b) a^=b^=a^=b 
#define lb(x) ((x)&(-(x)))
#define dalao 1000000007
#define inf 0x3f3f3f3f
#define N 4000010
using namespace std;
typedef long long ll;
#include<sys/mman.h>
struct buf{
	char*s;
	buf():s((char*)mmap(0,150000010,PROT_READ,MAP_PRIVATE,fileno(stdin),0)){}//用mmap直接防卡输入输出
	operator int(){
		int x=0,y=0;
		while(*s<48)
			if(*s++==45)y=1;
		while(*s>32)
			x=x*10+*s++-48;
		return y?-x:x;
	}
}it;//将数字转化为字符处理
int n,m,fa[N],ans,i;
inline int find(int x){while(fa[x]^x)x=fa[x]=fa[fa[x]];return x;}//位运算
inline void merge(int x,int y){x=find(x),y=find(y);if(x^y)fa[x]=y;}
矩阵相乘:
#include<bits/stdc++.h>
typedef unsigned long long u64;
const int P=1e9+7;
char rb[6000000],*rp=rb,ob[3000000],*op=ob;
//数字转化为字符ORZ
int _(){
	int x=0,f=1;
	while(*rp<48)*rp++=='-'?f=-1:0;
	while(*rp>47)x=x*10+*rp++-48;
	return x*f;
}
void pr(int x){
	int ss[15],sp=0;
	do ss[++sp]=x%10,x/=10;while(x);
	while(sp)*op++=ss[sp--]+48;
}
int n,p,m;
int a[507][507],b[507][507];
u64 c[507];
int fix(int x){return x+(x>>31&P);}
int main(){
	fread(rb,1,sizeof(rb),stdin);
	n=_(),p=_(),m=_();
	for(int i=1;i<=n;++i)
		for(int j=1;j<=p;++j)a[i][j]=fix(_());
	for(int i=1;i<=p;++i)
		for(int j=1;j<=m;++j)b[i][j]=fix(_());
	int m1=m-m%8;
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j)c[j]=0;
		for(int k=1;k<=p;++k){
			int *y=b[k];
			u64 x=a[i][k],*z=c;
			for(int j=8;j<=m1;j+=8){
				z[1]+=x*y[1];
				z[2]+=x*y[2];
				z[3]+=x*y[3];
				z[4]+=x*y[4];
				z[5]+=x*y[5];
				z[6]+=x*y[6];
				z[7]+=x*y[7];
				z[8]+=x*y[8];
				z+=8,y+=8;
			}
			y=b[k];
			for(int j=m1+1;j<=m;++j)c[j]+=x*y[j];
			if(!(k&15))
			for(int j=1;j<=m;++j)c[j]-=(c[j]>>30)*P;
		}
		for(int j=1;j<=m;++j)pr(c[j]%P),*op++=32;
		*op++=10;
	}
	fwrite(ob,1,op-ob,stdout);
	return 0;
}

然后。。一些奇技淫巧,比如filebuf,cout.rdbuf

#include <bits/stdc++.h>

const int OUT_LEN = 10000000;

char obuf[OUT_LEN], *oh = obuf;
std::streambuf *fb;

inline void print(char c) {
    oh == obuf + OUT_LEN ? (fb->sputn(obuf, OUT_LEN), oh = obuf) : 0;
    *oh++ = c;
}

template <class T>
inline void print(T x) {
    static int buf[30], cnt;
    for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 | 48;
    while (cnt) print((char)buf[cnt--]);
}

inline void flush() { fb->sputn(obuf, oh - obuf); }

#define long long long

const int MAXN = 3000001;

int inv[MAXN];

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(NULL);
    std::cout.tie(NULL);
    fb = std::cout.rdbuf();
    register int n, mod;
    std::cin >> n >> mod;//以求逆元为例
    inv[1] = 1;
    for (int i = 2; i <= n; i++)
        inv[i] = (long)(mod - mod / i) * inv[mod % i] % mod;
    for (register int i = 1; i <= n; i++) print(inv[i]), print('\n');
    flush();//除了print变化,并写了flush,其他解题过程都不变,这算是比较方便的防止卡输入输出的方法
    return 0;
}


线段树卡常也是常态。。


猜你喜欢

转载自blog.csdn.net/amous_x/article/details/80406652