模版
LaTeX
考场
编译命令:
g++ fhq.cpp -o fhq -O2 -std=c++14 -Wall -lm -fsanitize=address,undefined
快读快写
il int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
il void write(int x){
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
对拍
//windows
#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
int main(){
int miku=0;
while(1){
cout<<++miku<<'\n';
system("data.exe > in");
system("std.exe < in > std");
system("ans.exe < in > mine");
if(system("fc mine std"))return 0;
Sleep(200);
}
}
//linux
#include <bits/stdc++.h>
using namespace std;
int main(){
system("g++ data.cpp -o data");
system("g++ a.cpp -o a -O2 -std=c++14");
system("g++ b.cpp -o b -O2 -std=c++14");
int cnt=0;
while(1){
cout<<++cnt<<": ";
system("./data > in");
system("./a < in > out");
system("./b < in > ans");
if(system("diff out ans -B -w")){cout<<"WA"<<'\n';}
else cout<<"AC"<<'\n';
}
}
数据结构
树状数组
#include <bits/stdc++.h>
using namespace std;
int a[500001],tree[500001];
#define lowbit(x) (x&(-x))
int n,m;
void update(int x,int key){//单点修改
while(x<=n){
tree[x]+=key;
x+=lowbit(x);
}
}
int query(int x){//区间查询
int sum=0;
while(x>0){
sum+=tree[x];
x-=lowbit(x);
}
return sum;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
update(i,a[i]-a[i-1]);//将差分数组初始化
}
for(int i=1;i<=m;i++){
int doo,x,y,k;
cin>>doo;
if(doo==1){//修改[x,y]操作
cin>>x>>y>>k;
update(x,k);
update(y+1,-k);
}
else if(doo==2){//查询队列和操作;
cin>>x;
cout<<query(x)<<endl;
}
}
return 0;
}
//=============================================
#include <bits/stdc++.h>
using namespace std;
int a[500001],tree[500001];
#define lowbit(x) (x&(-x))
int n,m;
void update(int x,int key){//单点修改
while(x<=n){
tree[x]+=key;
x+=lowbit(x);
}
}
int query(int x){//单点查询
int sum=0;
while(x>0){
sum+=tree[x];
x-=lowbit(x);
}
return sum;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
update(i,a[i]);//将树状数组初始化
}
for(int i=1;i<=m;i++){
int doo,x,y;
cin>>doo>>x>>y;
if(doo==1){//修改x值操作
update(x,y);
}
else if(doo==2){//查询队列和操作;
cout<<(query(y)-query(x-1))<<endl;
}
}
return 0;
}
FHQ-Treap
#define M 100050
int rt(0),cnt(0);
namespace Treap{
struct node{
int l,r;
int key,pri;
int siz;
}t[M];
mt19937 gen(0);
il void add_point(int x){
++cnt;
t[cnt].l=t[cnt].r=0;
t[cnt].siz=1;
t[cnt].key=x;
t[cnt].pri=gen();
}
il void push_up(int k){
t[k].siz=t[t[k].l].siz+t[t[k].r].siz+1;
}
void split(int k,int x,int &L,int &R){
if(k==0){L=R=0;return;}
if(x<t[k].key){
R=k;
split(t[k].l,x,L,t[k].l);
}
else{
L=k;
split(t[k].r,x,t[k].r,R);
}
push_up(k);
}
int merge(int L,int R){
if(L==0||R==0)return L+R;
if(t[L].pri>t[R].pri){
t[L].r=merge(t[L].r,R);
push_up(L);
return L;
}
else{
t[R].l=merge(L,t[R].l);
push_up(R);
return R;
}
}
void insert(int x){
int L,R;
split(rt,x,L,R);
add_point(x);
int L1=merge(L,cnt);
rt=merge(L1,R);
}
void del(int x){
int L,R,p;
split(rt,x,L,R);
split(L,x-1,L,p);
p=merge(t[p].l,t[p].r);
rt=merge(merge(L,p),R);
}
int query_rank(int x){
int L,R;
split(rt,x-1,L,R);
int ans=t[L].siz+1;
rt=merge(L,R);
return ans;
}
int query_kth(int k,int x){
if(x==t[t[k].l].siz+1)return k;
else if(x<t[t[k].l].siz+1)return query_kth(t[k].l,x);
else return query_kth(t[k].r,x-t[t[k].l].siz-1);
}
int query_pre(int x){
int L,R;
split(rt,x-1,L,R);
int ans=t[query_kth(L,t[L].siz)].key;
rt=merge(L,R);
return ans;
}
int query_back(int x){
int L,R;
split(rt,x,L,R);
int ans=t[query_kth(R,1)].key;
rt=merge(L,R);
return ans;
}
}
signed main(){
// freopen("in","r",stdin);
// freopen("out","w",stdout);
int n=read();
for(int i=1;i<=n;i++){
int opt=read();
int x=read();
// cout<<opt<<endl;
if(opt==1) Treap::insert(x);
else if(opt==2) Treap::del(x);
else if(opt==3) Write(Treap::query_rank(x));
else if(opt==4) Write(Treap::t[Treap::query_kth(rt,x)].key);
else if(opt==5) Write(Treap::query_pre(x));
else if(opt==6) Write(Treap::query_back(x));
}
}
二逼平衡树
#include <bits/stdc++.h>
using namespace std;
#define il inline
#define ll long long
#define endl '\n'
#define M 100050
#define N 2000050
const int Nan=2147483647;
const int maxn=100000001;
namespace Testify{
il int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
il void write(ll x){
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
il void Write(ll x){write(x);puts("");}
il void writE(ll x){write(x);putchar(' ');}
}
using namespace Testify;
int root[N];
namespace Treap{
struct node{
int l,r;
int key,pri;
int siz;
}t[N];
int cnt(0);
mt19937 gen(0);
il void add_point(int x){
++cnt;
t[cnt].l=t[cnt].r=0;
t[cnt].key=x;
t[cnt].pri=gen();
t[cnt].siz=1;
}
il void push_up(int k){
t[k].siz=t[t[k].l].siz+t[t[k].r].siz+1;
}
void split(int k,int x,int &L,int &R){
if(k==0){L=R=0;return;}
if(x<t[k].key){
R=k;
split(t[k].l,x,L,t[k].l);
}
else{
L=k;
split(t[k].r,x,t[k].r,R);
}
push_up(k);
}
int merge(int L,int R){
if(L==0||R==0)return L+R;
if(t[L].pri>t[R].pri){
t[L].r=merge(t[L].r,R);
push_up(L);
return L;
}
else{
t[R].l=merge(L,t[R].l);
push_up(R);
return R;
}
}
il void insert(int k,int x){
int L,R;
split(root[k],x,L,R);
add_point(x);
root[k]=merge(merge(L,cnt),R);
}
il void del(int k,int x){
int L,R,p;
split(root[k],x,L,R);
split(L,x-1,L,p);
p=merge(t[p].l,t[p].r);
root[k]=merge(merge(L,p),R);
}
il int query_rank(int k,int x){
int L,R;
split(root[k],x-1,L,R);
int ans=t[L].siz;
root[k]=merge(L,R);
return ans;
}
int query_kth(int k,int x){
if(x==t[t[k].l].siz+1)return k;
else if(x<t[t[k].l].siz+1)return query_kth(t[k].l,x);
else return query_kth(t[k].r,x-t[t[k].l].siz-1);
}
int query_pre(int k,int x){
if(k==0)return -Nan;
if(x<=t[k].key)return query_pre(t[k].l,x);
int tmp=query_pre(t[k].r,x);
if(tmp==-Nan)return t[k].key;
else return tmp;
}
int query_back(int k,int x){
if(k==0)return Nan;
if(x>=t[k].key)return query_back(t[k].r,x);
int tmp=query_back(t[k].l,x);
if(tmp==Nan)return t[k].key;
else return tmp;
}
}
int a[M];
namespace Segment_Tree{
void build(int k,int l,int r){
for(int i=l;i<=r;i++)Treap::insert(k,a[i]);
if(l==r)return;
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
void update(int k,int l,int r,int pos,int val){
Treap::del(k,a[pos]);
Treap::insert(k,val);
if(l==r)return;
int mid=(l+r)>>1;
if(pos<=mid)update(k<<1,l,mid,pos,val);
else update(k<<1|1,mid+1,r,pos,val);
}
int query_rk(int k,int l,int r,int L,int R,int x){
if(L<=l&&r<=R)return Treap::query_rank(k,x);
int mid=(l+r)>>1;
int ans=0;
if(L<=mid)ans+=query_rk(k<<1,l,mid,L,R,x);
if(R>mid)ans+=query_rk(k<<1|1,mid+1,r,L,R,x);
return ans;
}
int query_pre(int k,int l,int r,int L,int R,int x){
if(L<=l&&r<=R)return Treap::query_pre(root[k],x);
int mid=(l+r)>>1;
int ans=-Nan;
if(L<=mid)ans=max(ans,query_pre(k<<1,l,mid,L,R,x));
if(R>mid)ans=max(ans,query_pre(k<<1|1,mid+1,r,L,R,x));
return ans;
}
int query_back(int k,int l,int r,int L,int R,int x){
if(L<=l&&r<=R)return Treap::query_back(root[k],x);
int mid=(l+r)>>1;
int ans=Nan;
if(L<=mid)ans=min(ans,query_back(k<<1,l,mid,L,R,x));
if(R>mid)ans=min(ans,query_back(k<<1|1,mid+1,r,L,R,x));
return ans;
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n=read(),m=read();
for(int i=1;i<=n;i++)a[i]=read();
Segment_Tree::build(1,1,n);
while(m--){
int opt=read();
if(opt==1){
int l=read(),r=read(),k=read();
cout<<Segment_Tree::query_rk(1,1,n,l,r,k)+1<<endl;
}else if(opt==2){
int l=read(),r=read(),k=read();
int L=0,R=maxn,mid,ans;
while(L<=R){
mid=(L+R)>>1;
if(Segment_Tree::query_rk(1,1,n,l,r,mid)+1<=k){L=mid+1;ans=mid;}
else R=mid-1;
}
cout<<ans<<endl;
}else if(opt==3){
int pos=read(),k=read();
Segment_Tree::update(1,1,n,pos,k);
a[pos]=k;
}else if(opt==4){
int l=read(),r=read(),k=read();
cout<<Segment_Tree::query_pre(1,1,n,l,r,k)<<endl;
}else if(opt==5){
int l=read(),r=read(),k=read();
cout<<Segment_Tree::query_back(1,1,n,l,r,k)<<endl;
}
}
}
文艺平衡树
int rt(0);
namespace Treap{
struct node{
int l,r;
int key,pri;
int siz,tag;
}t[M];
mt19937 gen(0);
int cnt(0);
il void add_point(int x){
++cnt;
t[cnt].key=x;
t[cnt].l=t[cnt].r=0;
t[cnt].siz=1;
t[cnt].pri=gen();
}
il void push_up(int k){
t[k].siz=t[t[k].l].siz+t[t[k].r].siz+1;
}
il void push_down(int k){
if(!t[k].tag)return;
swap(t[k].l,t[k].r);
t[t[k].l].tag^=1;
t[t[k].r].tag^=1;
t[k].tag=0;
}
void split(int k,int x,int &L,int &R){
if(k==0){L=R=0;return;}
push_down(k);
if(x<t[t[k].l].siz+1){
R=k;
split(t[k].l,x,L,t[k].l);
}
else{
L=k;
split(t[k].r,x-t[t[k].l].siz-1,t[k].r,R);
}
push_up(k);
}
int merge(int L,int R){
if(L==0||R==0)return L+R;
if(t[L].pri>t[R].pri){
push_down(L);
t[L].r=merge(t[L].r,R);
push_up(L);
return L;
}
else{
push_down(R);
t[R].l=merge(L,t[R].l);
push_up(R);
return R;
}
}
void swp(int x,int y){
int L,R,p;
split(rt,y,L,R);
split(L,x-1,L,p);
t[p].tag^=1;
rt=merge(merge(L,p),R);
}
void output(int k){
if(k==0)return;
push_down(k);
output(t[k].l);
writE(t[k].key);
output(t[k].r);
}
}
signed main(){
int n=read(),m=read();
for(int i=1;i<=n;i++){
Treap::add_point(i);
rt=Treap::merge(rt,Treap::cnt);
}
while(m--){
int L=read(),R=read();
Treap::swp(L,R);
}
Treap::output(rt);
return 0;
}
吉司机线段树
#include <bits/stdc++.h>
using namespace std;
#define il inline
#define ll long long
const int M=500010;
il int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
il void write(ll x){
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
int a[M];
namespace Segment_Tree{
struct node{
ll sum;
int mxa,mxb,smx,cnt;
int tag1,tag2,tag3,tag4;
}t[M<<2];
il void push_up(int k){
t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
t[k].mxa=max(t[k<<1].mxa,t[k<<1|1].mxa);
t[k].mxb=max(t[k<<1].mxb,t[k<<1|1].mxb);
if(t[k<<1].mxa==t[k<<1|1].mxa){
t[k].smx=max(t[k<<1].smx,t[k<<1|1].smx);
t[k].cnt=t[k<<1].cnt+t[k<<1|1].cnt;
}else if(t[k<<1].mxa>t[k<<1|1].mxa){
t[k].smx=max(t[k<<1].smx,t[k<<1|1].mxa);
t[k].cnt=t[k<<1].cnt;
}else{
t[k].smx=max(t[k<<1|1].smx,t[k<<1].mxa);
t[k].cnt=t[k<<1|1].cnt;
}
}
il void add_tag(int k,int l,int r,int t1,int t2,int t3,int t4){
t[k].sum+=1ll*t1*t[k].cnt+1ll*t2*(r-l+1-t[k].cnt);
t[k].mxb=max(t[k].mxb,t[k].mxa+t3);
t[k].mxa+=t1;
if(t[k].smx!=INT_MIN)t[k].smx+=t2;
t[k].tag3=max(t[k].tag3,t[k].tag1+t3);
t[k].tag4=max(t[k].tag4,t[k].tag2+t4);
t[k].tag1+=t1;
t[k].tag2+=t2;
}
il void push_down(int k,int l,int r){
int maxn=max(t[k<<1].mxa,t[k<<1|1].mxa);
int mid=(l+r)>>1;
if(t[k<<1].mxa==maxn)add_tag(k<<1,l,mid,t[k].tag1,t[k].tag2,t[k].tag3,t[k].tag4);
else add_tag(k<<1,l,mid,t[k].tag2,t[k].tag2,t[k].tag4,t[k].tag4);
if(t[k<<1|1].mxa==maxn)add_tag(k<<1|1,mid+1,r,t[k].tag1,t[k].tag2,t[k].tag3,t[k].tag4);
else add_tag(k<<1|1,mid+1,r,t[k].tag2,t[k].tag2,t[k].tag4,t[k].tag4);
t[k].tag1=t[k].tag2=t[k].tag3=t[k].tag4=0;
}
void build(int k,int l,int r){
if(l==r){
t[k].sum=t[k].mxa=t[k].mxb=a[l];
t[k].smx=INT_MIN;
t[k].cnt=1;
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
push_up(k);
}
void update_add(int k,int l,int r,int L,int R,int x){
if(L<=l&&r<=R){
add_tag(k,l,r,x,x,x,x);
return;
}
push_down(k,l,r);
int mid=(l+r)>>1;
if(L<=mid)update_add(k<<1,l,mid,L,R,x);
if(R>mid)update_add(k<<1|1,mid+1,r,L,R,x);
push_up(k);
}
void update_min(int k,int l,int r,int L,int R,int x){
if(x>=t[k].mxa)return;
if(L<=l&&r<=R&&x>t[k].smx){
t[k].sum-=1ll*t[k].cnt*(t[k].mxa-x);
t[k].tag1-=(t[k].mxa-x);
t[k].mxa=x;
// add_tag(k,l,r,x-t[k].mxa,x-t[k].mxa,0,0);
return;
}
push_down(k,l,r);
int mid=(l+r)>>1;
if(L<=mid)update_min(k<<1,l,mid,L,R,x);
if(R>mid)update_min(k<<1|1,mid+1,r,L,R,x);
push_up(k);
}
ll query_sum(int k,int l,int r,int L,int R){
if(L<=l&&r<=R)return t[k].sum;
push_down(k,l,r);
int mid=(l+r)>>1;
ll ans=0;
if(L<=mid)ans+=query_sum(k<<1,l,mid,L,R);
if(R>mid)ans+=query_sum(k<<1|1,mid+1,r,L,R);
return ans;
}
int query_mxa(int k,int l,int r,int L,int R){
if(L<=l&&r<=R)return t[k].mxa;
push_down(k,l,r);
int mid=(l+r)>>1;
int ans=INT_MIN;
if(L<=mid)ans=max(ans,query_mxa(k<<1,l,mid,L,R));
if(R>mid)ans=max(ans,query_mxa(k<<1|1,mid+1,r,L,R));
return ans;
}
int query_mxb(int k,int l,int r,int L,int R){
if(L<=l&&r<=R)return t[k].mxb;
push_down(k,l,r);
int mid=(l+r)>>1;
int ans=INT_MIN;
if(L<=mid)ans=max(ans,query_mxb(k<<1,l,mid,L,R));
if(R>mid)ans=max(ans,query_mxb(k<<1|1,mid+1,r,L,R));
return ans;
}
}
int main(){
// freopen("P6242_1.in","r",stdin);
// freopen("P6242_1.out","w",stdout);
int n=read(),m=read();
for(int i=1;i<=n;i++)a[i]=read();
Segment_Tree::build(1,1,n);
while(m--){
int opt=read(),l=read(),r=read();
if(opt==1){
int x=read();
Segment_Tree::update_add(1,1,n,l,r,x);
}else if(opt==2){
int x=read();
Segment_Tree::update_min(1,1,n,l,r,x);
}else if(opt==3){
write(Segment_Tree::query_sum(1,1,n,l,r));
puts("");
}else if(opt==4){
write(Segment_Tree::query_mxa(1,1,n,l,r));
puts("");
}else{
write(Segment_Tree::query_mxb(1,1,n,l,r));
puts("");
}
}
return 0;
}
主席树
#include <bits/stdc++.h>
using namespace std;
#define il inline
#define ll long long
namespace Testify{
il ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
il void write(ll x){
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
il void Write(ll x){write(x);puts("");}
il void writE(ll x){write(x);putchar(' ');}
}
using namespace Testify;
#define M 1000050
int tim(0);
ll a[M];
int root[M];
namespace Segment_Tree{
struct node{
int l,r;
ll val;
}t[M<<5];
int cnt(0);
int build_tree(int l,int r){
int rt=++cnt;
t[rt].l=l,t[rt].r=r;
if(l==r){
t[rt].val=a[l];
return rt;
}
int mid=(l+r)>>1;
t[rt].l=build_tree(l,mid);
t[rt].r=build_tree(mid+1,r);
return rt;
}
int update(int pre,int l,int r,int x,int val){
int rt=++cnt;
t[rt]=t[pre];
if(l==r){
t[rt].val=val;
return rt;
}
int mid=(l+r)>>1;
if(x<=mid)t[rt].l=update(t[pre].l,l,mid,x,val);
else t[rt].r=update(t[pre].r,mid+1,r,x,val);
return rt;
}
int query(int rt,int l,int r,int x){
if(l==r)return t[rt].val;
int mid=(l+r)>>1;
if(x<=mid)return query(t[rt].l,l,mid,x);
else return query(t[rt].r,mid+1,r,x);
}
}
signed main(){
int n=read(),m=read();
for(int i=1;i<=n;i++)a[i]=read();
root[0]=Segment_Tree::build_tree(1,n);
for(int i=1;i<=m;i++){
int his=read(),opt=read();
if(opt==1){
int pos=read(),val=read();
root[i]=Segment_Tree::update(root[his],1,n,pos,val);
}
else{
int pos=read();
Write(Segment_Tree::query(root[his],1,n,pos));
root[i]=root[his];
}
// cout<<his<<endl;
// cout<<root[i]<<" "<<root[his]<<endl;
}
}
数论
线性筛质数
const int M=1e8+10;
int pri[M],cnt(0);
bool vis[M];
int main(){
int n=read(),q=read();
vis[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
pri[++cnt]=i;
}
for(int j=1;j<=cnt&&i*pri[j]<=n;j++){
vis[i*pri[j]]=1;
if(i%pri[j]==0)break;
}
}
while(q--){
int x=read();
cout<<pri[x]<<'\n';
}
}
高斯消元
#include <bits/stdc++.h>
using namespace std;
double a[100][100];
const double eps=1e-6;
int n;
int gauss(){
int r=0;
for(int i=1;i<=n;i++){
r=i;
for(int k=i;k<=n;k++)
if(fabs(a[k][i])>eps){
r=k;break;
}
if(r!=i)swap(a[i],a[r]);
if(fabs(a[i][i])<eps){
return 0;
}
for(int j=n+1;j>=i;j--)
a[i][j]/=a[i][i];
for(int k=i+1;k<=n;k++)
for(int j=n+1;j>=i;j--)
a[k][j]-=a[k][i]*a[i][j];
}
for(int i=n-1;i>=1;i--)
for(int j=i+1;j<=n;j++)
a[i][n+1]-=a[i][j]*a[j][n+1];
return 1;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n+1;j++){
cin>>a[i][j];
}
}
if(gauss()==1){
for(int i=1;i<=n;i++){
printf("%.2lf\n",a[i][n+1]);
}
}
else cout<<"No Solution"<<endl;
return 0;
}
拓展欧几里得定理
int x,y;
inline void ex_gcd(int a,int b){
if(!b){
x=1;
y=0;
return;
}
ex_gcd(b,a%b);
int k=x;
x=y;
y=k-(a/b)*y;
return;
}
int main(){
int a,b;
cin>>a>>b;
ex_gcd(a,b);
cout<<(x%b+b)%b<<endl;
return 0;
}
拉格朗日插值
const int mod=998244353;
const int M=2010;
il ll fast_pow(ll x,int a){
ll ans=1;
while(a){
if(a&1)ans=ans*x%mod;
x=x*x%mod;
a>>=1;
}
return ans;
}
int x[M],y[M];
signed main(){
int n=read(),k=read();
for(int i=1;i<=n;i++) x[i]=read(),y[i]=read();
ll ans=0;
for(int i=1;i<=n;i++){
ll tmp1=y[i],tmp2=1;
for(int j=1;j<=n;j++){
if(j==i)continue;
tmp1=tmp1*((k-x[j]+mod)%mod)%mod;
tmp2=tmp2*((x[i]-x[j]+mod)%mod)%mod;
}
tmp1=tmp1*fast_pow(tmp2,mod-2)%mod;
ans=ans+tmp1;
ans%=mod;
}
cout<<ans;
return 0;
}
Dirichlet 前缀和
#include <bits/stdc++.h>
using namespace std;
#define M 20000050
#define uint unsigned int
uint seed;
inline uint getnext(){
seed^=seed<<13;
seed^=seed>>17;
seed^=seed<<5;
return seed;
}
uint a[M],p[M],cnt(0);
bool vis[M];
signed main(){
int n;
cin>>n>>seed;
for(int i=1;i<=n;i++){
a[i]=getnext();
// cout<<a[i]<<" ";
}
for(int i=2;i<=n;i++){
if(!vis[i])p[++cnt]=i;
for(int j=1;i*p[j]<=n&&j<=cnt;j++){
vis[i*p[j]]=1;
if(i%p[j]==0)break;
}
}
for(int i=1;i<=cnt;i++){
for(int j=1;p[i]*j<=n;j++){
a[p[i]*j]+=a[j];
}
}
uint ans=0;
for(int i=1;i<=n;i++){ans^=a[i];}
cout<<ans;
}
卢卡斯定理
int mod;
il int fast_pow(int a,int x){
int ans=1;
while(x){
if(x&1)ans=ans*a%mod;
a=a*a%mod;
x>>=1;
}
return ans;
}
int f[M],g[M];
il int get_c(int x,int y){
return f[x]*fast_pow(f[y],mod-2)*fast_pow(f[x-y],mod-2)%mod;
}
il int lucas(int x,int y){
if(y==0)return 1;
return (lucas(x/mod,y/mod)*get_c(x%mod,y%mod))%mod;
}
main(void){
int T;
cin>>T;
f[0]=g[0]=1;
while(T--){
int n,m;
cin>>n>>m>>mod;
for(int i=1;i<=mod;i++)f[i]=f[i-1]*i%mod;
cout<<lucas(n+m,n)<<endl;
}
}
拓展卢卡斯定理
int x,y;
inline void ex_gcd(int a,int b){
if(!b){
x=1;
y=0;
return;
}
ex_gcd(b,a%b);
int k=x;
x=y;
y=k-(a/b)*y;
return;
}
il int fast_pow(int a,int b,int p){
int ans=1;
while(b){
if(b&1)ans=ans*a%p;
a=a*a%p;
b>>=1;
}
return (ans%p+p)%p;
}
il int get_inv(int a,int p){
ex_gcd(a,p);//std::cout<<a<<" "<<p<<" "<<x<<" "<<y<<endl;
return (x%p+p)%p;
}
int n,m,P;
int a[M],b[M];
il int F(int n,int p,int pk){
if(n==0)return 1;
int arc=1,aea=1;
for(int i=1;i<=pk;i++){
if(i%p)arc=arc*i%pk;
}
arc=fast_pow(arc,n/pk,pk);
for(int i=pk*(n/pk);i<=n;i++){
if(__gcd(i,p)==1)aea=aea*(i%pk)%pk;
}
return ((F(n/p,p,pk)*arc%pk)%pk*aea%pk+pk)%pk;
}
il int G(int n,int p){
if(n<p)return 0;
return G(n/p,p)+n/p;
}
il int c_mod_pk(int n,int m,int p,int pk){
int f1=F(n,p,pk);
//cout<<F(m,p,pk)<<endl;
int f2=get_inv(F(m,p,pk),pk);
//cout<<F(n-m,p,pk)<<endl;
int f3=get_inv(F(n-m,p,pk),pk);
int k=G(n,p)-G(m,p)-G(n-m,p);
int pg=fast_pow(p,k,pk);
return (((f1*f2%pk)%pk*f3%pk)%pk*pg%pk)%pk;
}
il int ex_lucas(){
int ep=P,cnt=0;
for(int i=2;i*i<=P;i++){
if(ep%i==0){
int arc=1;
while(ep%i==0){
arc*=i;
ep/=i;
}
a[++cnt]=arc;
b[cnt]=c_mod_pk(n,m,i,arc);
}
}
if(ep>1){
a[++cnt]=ep;
//std::cout<<ep<<endl;
b[cnt]=c_mod_pk(n,m,ep,ep);
}
int ans=0;
//cout<<cnt<<endl;
for(int i=1;i<=cnt;i++){
int c=P/a[i];
//cout<<c<<" "<<a[i]<<endl;
int cc=get_inv(c,a[i]);
//std::cout<<"* "<<b[i]<<" "<<c<<" "<<cc<<endl;
ans=(ans+b[i]*c%P*cc%P)%P;
}
return ans;
}
main(){
cin>>n>>m>>P;
std::cout<<ex_lucas()<<endl;
return 0;
}
中国剩余定理
int m[10],b[10],M,ans;
int x,y;
inline void exgcd(int a,int b){
if(b==0){
x=1;
y=0;
return;
}
exgcd(b,a%b);
int k=x;
x=y;
y=k-(a/b)*y;
return;
}
main(){
int n;
M=1;
cin>>n;
for(int i=1;i<=n;i++){
cin>>m[i]>>b[i];
M*=m[i];
}
for(int i=1;i<=n;i++){
int c=M/m[i];
exgcd(c,m[i]);
ans+=b[i]*c*x%M;
}
cout<<(ans%M+M)%M;
}
拓展中国剩余定理
#include <bits/stdc++.h>
using namespace std;
#define il inline
#define int __int128
#define mem(CSZPY) memset(CSZPY,0,sizeof(CSZPY))
#define MM 100050
int M,a[MM],m[MM];
int x,y;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline void write(int x){
if(x<0)putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
return;
}
il int exgcd(int a,int b){
if(!b){
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b);
int k=x;
x=y;
y=k-(a/b)*y;
return d;
}
il int excrt(int n){
int m1=m[1],m2,a1=a[1],a2;
for(int i=2;i<=n;i++){
m2=m[i],a2=a[i];
int g=exgcd(m1,m2);
int p=x;
if((a2-a1)%g){return -1;}
p=p*(a2-a1)/g;
p=(p%(m2/g)+(m2/g))%(m2/g);
a1=a1+m1*p;
m1=m1*m2/g;
}//cerr<<"======"<<endl;
return (a1%m1+m1)%m1;
}
main(){
int n=read();
for(int i=1;i<=n;i++){
m[i]=read(),a[i]=read();
}
write(excrt(n));
return 0;
}
线性基
namespace Xor_Linear_Basis{
ll a[M];
bool zero=false;
il void insert(ll x){
for(int i=M;i>=0;i--){
if((x>>i)==1)
if(a[i]==0){a[i]=x;return;}
else x^=a[i];
}
zero=true;
}
bool check(ll x){
for(int i=M;i>=0;i--){
if((x>>i)==1)
if(a[i]==0)return false;
else x^=a[i];
}
return true;
}
ll query_max(){
ll ans=0;
for(int i=M;i>=0;i--)
if((ans^a[i])>ans)ans=ans^a[i];
return ans;
}
ll query_min(){
if(zero)return 0;
for(int i=0;i<=M;i++)if(a[i])return a[i];
}
ll query_K(int k){
if(zero)k--;
if(!k)return 0;
for(int i=1;i<=M;i++){
for(int j=1;j<=i;j++){
if(a[i]&((1ll<<j)-1))a[i]^=a[j-1];
}
}
ll ans=0;
for(int i=0;i<=M;i++)
if(a[i]){
if(k&1)ans^=a[i];
k>>=1;
}
return ans;
}
}
图论
dij
int dis[M];
bool vis[M];
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>> > q;
int main(){
int n=read(),m=read(),st=read();
for(int i=1;i<=m;i++){
int u=read(),v=read(),w=read();
add(u,v,w);
add(v,u,w);
}
memset(dis,0x7f,sizeof(dis));
dis[st]=0;
q.push({0,st});
while(!q.empty()){
pair<int,int> x=q.top();
q.pop();
if(vis[x.second])continue;
vis[x.second]=1;
for(int i=head[x.second];i;i=e[i].nxt){
int y=e[i].v;
if(vis[y])continue;
if(dis[y]>x.first+e[i].w){
dis[y]=x.first+e[i].w;
q.push({dis[y],y});
}
}
}
for(int i=1;i<=n;i++){
cout<<dis[i]<<" ";
}
return 0;
}
SPFA and 负环
dis[1]=0;
vis[1]=1;
neg[1]=1;
q.push(1);
while(!q.empty()){
int x=q.front();q.pop();
vis[x]=0;
for(int i=head[x];i;i=e[i].nxt){
int y=e[i].v;
if(dis[x]+e[i].w<dis[y]){
dis[y]=dis[x]+e[i].w;
if(!vis[y]){
vis[y]=1;
q.push(y);
neg[y]++;
if(neg[y]>n){
puts("YES");
goto miku;
}
}
}
}
}
puts("NO");
miku:continue;
倍增lca
il void dfs(int x,int fa){
dep[x]=dep[fa]+1;
f[x][0]=fa;
for(int i=1;i<=23;i++)
f[x][i]=f[f[x][i-1]][i-1];
for(int i=head[x];i;i=e[i].next){
int y=e[i].v;
if(y!=fa)dfs(y,x);
}
}
il int lca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
for(int i=23;i>=0;i--){
if(dep[f[x][i]]>=dep[y]){
x=f[x][i];
}
}
if(x==y)return x;
for(int i=23;i>=0;i--){
if(f[x][i]!=f[y][i]){
x=f[x][i],y=f[y][i];
}
}
return f[x][0];
}
树链剖分
int siz[M],dep[M],f[M],top[M],son[M];
il void dfs1(int x,int fa){
dep[x]=dep[fa]+1;
f[x]=fa;
siz[x]=1;
for(int i=head[x];i;i=e[i].next){
int y=e[i].v;
if(y!=fa){
dfs1(y,x);
siz[x]+=siz[y];
if(!son[x] || siz[y]>siz[son[x]]){
son[x]=y;
}
}
}
}
il void dfs2(int x,int tpx){
top[x]=tpx;
if(!son[x])return;
dfs2(son[x],tpx);
for(int i=head[x];i;i=e[i].next){
int y=e[i].v;
if(y!=f[x] && y!=son[x]){
dfs2(y,y);
}
}
}
il int lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=f[top[x]];
}
return dep[x]<dep[y]?x:y;
}
int main(){
int n,m,s;
cin>>n>>m>>s;
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
add_edge(u,v);
add_edge(v,u);
}
dfs1(s,0);
dfs2(s,s);
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
cout<<lca(x,y)<<endl;
}
return 0;
}
点双
struct edge{
int u,v,next;
};
edge e[M];
int head[M],cnt;
void add_edge(int u,int v){
e[++cnt].u=u;
e[cnt].v=v;
e[cnt].next=head[u];
head[u]=cnt;
}
int dfn[M],low[M],stk[M],ecnt,dcc,top;
vector<int> ans[M];
void tarjan(int x,int fa){
dfn[x]=low[x]=++ecnt;
stk[++top]=x;
if(x==fa && !head[x]){
ans[++dcc].push_back(x);
return;
}
for(int i=head[x];i;i=e[i].next){
int y=e[i].v;
if(!dfn[y]){
tarjan(y,x);
low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x]){
++dcc;
int yy;
do{
yy=stk[top--];
ans[dcc].push_back(yy);
}while(yy!=y);
ans[dcc].push_back(x);
}
}
else{
low[x]=min(low[x],dfn[y]);
}
}
}
int main(){
cnt=1;
int n=read(),m=read();
for(int i=1;i<=m;i++){
int u=read(),v=read();
if(u==v){
continue;
}
add_edge(u,v);
add_edge(v,u);
}
for(int i=1;i<=n;i++){
if(!dfn[i])tarjan(i,i);
}
cout<<dcc<<endl;
for(int i=1;i<=dcc;i++){
cout<<ans[i].size()<<" ";
for(int j=0;j<ans[i].size();j++){
cout<<ans[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
边双
struct edge{
int v,next;
};
edge e[M];
int head[M],ent=1;
void add_edge(int u,int v){
e[++ent].v=v;
e[ent].next=head[u];
head[u]=ent;
}
int dfn[M],low[M],stk[M],tot,dnt,top;
vector<int> dcc[M];
void tarjan(int x,int in_edge){
dfn[x]=low[x]=++tot;
stk[++top]=x;
for(int i=head[x];i;i=e[i].next){
int y=e[i].v;
if(!dfn[y]){
tarjan(y,i);
low[x]=min(low[x],low[y]);
}
else if(i!=(in_edge^1)){
low[x]=min(low[x],dfn[y]);
}
}
if(low[x]==dfn[x]){
int y;dnt++;
do{
y=stk[top--];
dcc[dnt].push_back(y);
}while(y!=x);
}
}
int main(){
int n=read(),m=read();
for(int i=1;i<=m;i++){
int a=read(),b=read();
add_edge(a,b);
add_edge(b,a);
}
for(int i=1;i<=n;i++){
if(!dfn[i])tarjan(i,0);
}
cout<<dnt<<endl;
for(int i=1;i<=dnt;i++){
cout<<dcc[i].size()<<" ";
for(int j=0;j<dcc[i].size();j++){
cout<<dcc[i][j]<<" ";
}
puts("");
}
return 0;
}
Edmonds-Karp
struct node{
int w,v,nxt;
}e[M<<1];
int head[M],cnt=1;
il void add(int u,int v,int w){
e[++cnt].v=v;
e[cnt].w=w;
e[cnt].nxt=head[u];
head[u]=cnt;
}
int n,m,s,t;
int pre[M],dis[M];
queue<int> q;
il int bfs(){
for(int i=1;i<=n;i++)pre[i]=0,dis[i]=1145141919;
q.push(s);
while(!q.empty()){
int x=q.front();q.pop();
for(int i=head[x];i;i=e[i].nxt){
int y=e[i].v;
if(pre[y]||y==s||!e[i].w)continue;
q.push(y);
dis[y]=min(dis[x],e[i].w);
pre[y]=i;
}
}
if(!pre[t])return -1;
return dis[t];
}
main(){
n=read(),m=read(),s=read(),t=read();
for(int i=1;i<=m;i++){
int u=read(),v=read(),w=read();
add(u,v,w);
add(v,u,0);
}
ll ans=0;
while(true){
int k=bfs();
if(k==-1)break;
ans+=k;
int now=t;
while(now!=s){
e[pre[now]].w-=k;
e[pre[now]^1].w+=k;
now=e[pre[now]^1].v;
}
}
cout<<ans;
return 0;
}
Dinic
#include <bits/stdc++.h>
using namespace std;
#define il inline
#define ll long long
#define int long long
il ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int M=5010;
const ll inf=1ll<<60;
struct node{
int v,nxt;
ll w;
}e[M<<1];
int head[M],cnt=1;
il void add(int u,int v,ll w){
e[++cnt].v=v;
e[cnt].w=w;
e[cnt].nxt=head[u];
head[u]=cnt;
}
int n,m,s,t;
int dep[M],now[M];
queue<int> q;
il bool bfs(){
while(!q.empty())q.pop();
for(int i=1;i<=n;i++)dep[i]=-1;
dep[s]=0;
q.push(s);
now[s]=head[s];
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=head[x];i;i=e[i].nxt){
int y=e[i].v;
if(e[i].w>0&&dep[y]==-1){
q.push(y);
now[y]=head[y];
dep[y]=dep[x]+1;
if(y==t)return 1;
}
}
}
return 0;
}
int dfs(int x,ll sum){
if(x==t)return sum;
ll k,flow=0;
for(int i=now[x];i&∑i=e[i].nxt){
now[x]=i;
int y=e[i].v;
if(e[i].w>0&&(dep[y]==dep[x]+1)){
k=dfs(y,min(sum,e[i].w));
if(k==0)dep[y]=-1;
e[i].w-=k;
e[i^1].w+=k;
flow+=k;
sum-=k;
}
}
return flow;
}
main(){
n=read(),m=read(),s=read(),t=read();
for(int i=1;i<=m;i++){
int u=read(),v=read();
ll w=read();
add(u,v,w);
add(v,u,0);
}
ll ans=0;
while(bfs())ans+=dfs(s,inf);
cout<<ans;
return 0;
}
字符串
字符串哈希
#include <bits/stdc++.h>
using namespace std;
#define ull unsigned long long
ull a[10010];
char s[10010];
ull Hash(char *s){
ull P=131,H=0;
int len=strlen(s);
for(int i=0;i<len;i++)H=H*P+s[i]-'a'+1;
return H;
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>s;
a[i]=Hash(s);
}
int ans=0;
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){if(a[i-1]!=a[i])ans++;}
cout<<ans<<endl;
return 0;
}
马拉车
#include <bits/stdc++.h>
using namespace std;
#define S 50000050
char a[S],s[S<<1];
int len;
int p[S];
inline void manacher(){
s[0]='$',s[1]='#';
for(int i=0;i<len;i++){
s[(i<<1)+2]=a[i];
s[(i<<1)+3]='#';
}
len=(len<<1)+2;
s[len]='@';
int maxright=0,mid;
for(int i=1;i<len;i++){
if(i<maxright)p[i]=min(p[(mid<<1)-i],p[mid]+mid-i);
else p[i]=1;
for(;s[i+p[i]]==s[i-p[i]];++p[i]);
if(p[i]+i>maxright){
maxright=p[i]+i;
mid=i;
}
}
}
int main(){
cin>>a;
len=strlen(a);
int ans=1;
manacher();
for(int i=0;i<len;i++){
ans=max(ans,p[i]);
}
cout<<ans-1<<endl;
return 0;
}
AC自动机
struct node{
int son[30];
int fail,end;
}t[M];
int cnt(0);
il void Insert(char *s){
int pos=0;
for(int i=0;s[i];i++){
int ch=s[i]-'a';
if(t[pos].son[ch]==0)t[pos].son[ch]=cnt++;
pos=t[pos].son[ch];
}
t[pos].end++;
return;
}
il void get_Fail(){
queue<int> q;
for(int i=0;i<26;i++){//第一层入队
if(t[0].son[i])q.push(t[0].son[i]);
}
while(!q.empty()){
int pos=q.front();
q.pop();
for(int i=0;i<26;i++){
if(t[pos].son[i]){
t[t[pos].son[i]].fail=t[t[pos].fail].son[i];
q.push(t[pos].son[i]);
}
else t[pos].son[i]=t[t[pos].fail].son[i];
}
}
}
il int query(char *s){
int ans=0;
int pos=0;
for(int i=0;s[i];i++){
int ch=s[i]-'a';
pos=t[pos].son[ch];
int tmp=pos;
while(tmp&&t[tmp].end!=-1){
ans+=t[tmp].end;
t[tmp].end=-1;
tmp=t[tmp].fail;
}
}
return ans;
}
char str[M];
int main(){
cnt=1;
int n=read();
while(n--){
cin>>str;
Insert(str);
}
get_Fail();
cin>>str;
cout<<query(str)<<endl;
return 0;
}
KMP
#include <bits/stdc++.h>
using namespace std;
char s1[1000010];
char s2[1000010];
int Next[1000010];
int len;
inline void get_next(){
len=strlen(s2);
Next[0]=0;Next[1]=0;
for(int i=1;i<len;i++){
int j=Next[i];
while(j&&s2[i]!=s2[j])j=Next[j];
if(s2[i]==s2[j])Next[i+1]=j+1;
else Next[i+1]=j;
}
}
void write(int x){
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
return;
}
int main(){
cin>>s1>>s2;
get_next();
int j=0;
int len_main=strlen(s1);
for(int i=0;i<len_main;i++){
while(j&&s1[i]!=s2[j])j=Next[j];
if(s1[i]==s2[j])j++;
if(j==len){write(i-len+2);puts("");}
}
for(int i=1;i<=len;i++){write(Next[i]);printf(" ");}
return 0;
}
本文来自博客园,作者:CCComfy,转载请注明原文链接:https://www.cnblogs.com/cccomfy/p/17756154.html