之前卡常基本都是乘法改为加法,位运算,去绑定(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; }
线段树卡常也是常态。。