模板库
完善中……
优化
快读快输
inline int read(){
int t=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-') f=-f;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
t=t*10+ch-'0';
ch=getchar();
}
return t*f;
}
void write(int x){
if(x<0) {putchar('-');x=-x;}
if(x>9) write(x/10);
putchar(x%10+'0');
}
组合计数
逆元预处理
lx[0]=1;lx[1]=1;
for(int i=2;i<N;i++) lx[i]=lx[i-1]*i%mod;
inv[N-1]=ksm(lx[N-1],mod-2);
for(int i=N-2;i>=0;i--) inv[i]=(inv[i+1])*(i+1)%mod;
快速幂
int ksm(int x,int y) {int t=1;while(y){if(y&1)t=t*x%mod;x=x*x%mod;y>>=1;}return t;}
组合数
int C(int x,int y) {if(x<y) return 0;return lx[x]*inv[y]%mod*inv[x-y]%mod;}
lucas
int lucas(int x,int y) {
if(x<mod&&y<mod) return C[x][y];
return lucas(x%mod,y%mod)*lucas(x/mod,y/mod)%mod;
}
exgcd
void exgcd(int a,int b) {
if(b==0) {
y=0;x=1;return ;
}
exgcd(b,a%b);
tmp=x;
x=y;
y=tmp-y*(a/b);
}
数据结构
树状数组
#define int long long
#define lowbit(x) (x&(-x))
void add(int x,int y) {if(x==0) return ;while(x<N) {c[x]+=y;x+=lowbit(x);};}
int ask(int x) {int t=0;while(x) {t+=c[x];x-=lowbit(x);}return t;}
线段树
真是好标准一颗线段树,感觉自己已经很久没有写过build()了。
struct stu {
int maxx,minn,add;
friend stu operator +(stu a,stu b) {
a.minn=min(a.minn,b.minn);
a.maxx=max(a.maxx,b.maxx);
return a;
}
}t[N*4];
int read() {int x;cin>>x;return x;}
void spread(int p) {
if(t[p].add) {
t[p*2].add+=t[p].add;
t[p*2+1].add+=t[p].add;
t[p*2].minn+=t[p].add;
t[p*2+1].minn+=t[p].add;
t[p*2].maxx+=t[p].add;
t[p*2+1].maxx+=t[p].add;
t[p].add=0;
}
}
void change(int p,int l,int r,int tl,int tr,int k) {
if(tl<=l&&r<=tr) {
t[p].add+=k;
t[p].maxx+=k;
t[p].minn+=k;
return ;
}
spread(p);
int mid=(l+r)>>1;
if(tl<=mid) change(p*2,l,mid,tl,tr,k);
if(mid<tr) change(p*2+1,mid+1,r,tl,tr,k);
t[p].minn=min(t[p*2].minn,t[p*2+1].minn);
t[p].maxx=max(t[p*2].maxx,t[p*2+1].maxx);
}
stu ask(int p,int l,int r,int tl,int tr) {
if(tr<tl) {
return {-10000000,1000000000000,0};
}
if(tl<=l&&r<=tr) {
// cerr<<"Ask "<<p<<" "<<t[p].minn<<" "<<t[p].maxx<<" "<<l<<" "<<r<<endl;
return t[p];
}
spread(p);
int mid=(l+r)>>1;
stu ans; ans={0,0,0};
ans.minn=1e18;ans.maxx=-1e18;
if(tl<=mid) ans=ans+ask(p*2,l,mid,tl,tr);
if(mid<tr) ans=ans+ask(p*2+1,mid+1,r,tl,tr);
return ans;
}
void build(int p,int l,int r) {
t[p].add=0;t[p].minn=1e9;t[p].maxx=-1e9;
if(l==r) {
t[p].minn=t[p].maxx=min(l,n);
// cerr<<"Build "<<p<<" "<<t[p].minn<<" "<<t[p].maxx<<endl;
return ;
}
int mid=(l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].minn=min(t[p*2].minn,t[p*2+1].minn);
t[p].maxx=max(t[p*2].maxx,t[p*2+1].maxx);
}