这是板子,它很可爱

对拍&数据生成器

树生成器
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9;
const int N=1e6+5;
int n,m=10;
int d[N],p[N];
vector<pair<int,int>>  a;
int main(){
    // freopen("in","w",stdout);
    n=10;
    mt19937 rnd(time(0));
    for(int i=1;i<=n;++i){
    	d[i]=1;
	} 
    for(int i=1;i<=n-2;++i){
    	++d[p[i]=rnd()%n+1];
	}
    int now,pre;
	for(int i=1;i<=n;++i){
		if(d[i]==1){
			pre=now=i;
			break;
		}
	}
    for(int i=1;i<=n-2;++i){
        int f=p[i];
        a.push_back({now,f});
        if(--d[f]==1&&f<pre){
        	now=f;
		}
        else{
			while(d[++pre]!=1);
			now=pre;
		}
    }
    a.push_back({now,n});
    for(int i=0;i<a.size();i++){
    	cout<<a[i].first<<" "<<a[i].second<<endl;
	}
    return 0;
}
对拍
#include<bits/stdc++.h>
#include<windows.h>  
using namespace std;  
int main(){  
    int t=10;
    clock_t startTime,endTime;
    while(t--){ 
        system("data.exe > data.txt");  
        system("test.exe < data.txt > test.txt");  
        startTime = clock();
        system("std.exe < data.txt > std.txt");  
        endTime = clock();
        if(system("fc std.txt test.txt")){
			cout<<"Wrong Answer"<<endl;
			break;
		}
		else{
			cout<<"Accepted"<<endl;
		}
		cout<<"The run time is: "<<(double)(endTime-startTime)/CLOCKS_PER_SEC<<"s"<< endl;
    }  
    if(t==0) cout<<"no error"<<endl;  
    else cout<<"error"<<endl;
    return 0;  
}  

模拟栈

模拟栈
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
int top=0;
int s[maxn];
int t,n;
string s1;
signed main(){
	cin>>t;
	int x;
	while(t--){
		top=0;
		cin>>n;
		for(int i=1;i<=n;i++){
			cin>>s1;
			if(s1=="push"){
				cin>>x;
				top++;
				s[top]=x;
			}	
			else if(s1=="pop"){
				if(top==0){
					cout<<"Empty"<<endl;
				}
				else{
					top--;
				}
			}
			else if(s1=="size"){
				cout<<top<<endl;
			}
			else if(s1=="query"){
				if(top!=0){
					cout<<s[top]<<endl;
				}
				else{
					cout<<"Anguei!"<<endl;
				}
			}
		}
	}
	return 0;
}

Floyd

Floyd
#include<bits/stdc++.h>
#define int long long
using namespace std;
int arr[110][110];
int n,m;
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			arr[i][j]=1e17;
			if(i==j){
				arr[i][j]=0;
			}
		}
	}
	for(int i=1;i<=m;i++){
		int u,v,w;
		cin>>u>>v>>w;
		arr[u][v]=w;
		arr[v][u]=w;
	}
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				arr[i][j]=min(arr[i][j],arr[i][k]+arr[k][j]);
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cout<<arr[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
}

小根堆
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
int heap[maxn],siz;
void push(int x){
	int pos=siz++;
	while(pos>0){
		if(heap[(pos-1)/2]<=x){
			break;
		}
		heap[pos]=heap[(pos-1)/2];
		pos=(pos-1)/2;
	}
	heap[pos]=x;
	return;
}
void pop(){
	int pos=0;
	int x=heap[--siz];
	while(pos*2+1<siz){
		int t=(heap[pos*2+1]<heap[pos*2+2])?pos*2+1:pos*2+2;
		if(heap[t]>=x){
			break;
		}
		heap[pos]=heap[t];
		pos=t;
	}
	heap[pos]=x;
	return;
}
int top(){
	return heap[0];
}
int t,op;
signed main(){
	cin>>t;
	int x;
	while(t--){
		cin>>op;
		if(op==1){
			cin>>x;
			push(x);
		}
		else if(op==2){
			cout<<top()<<endl;
		}
		else if(op==3){
			pop();
		}
	}
	return 0;
}

模拟队列

模拟队列
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
int n,op;
int front=0;
int last=0;
int q[maxn];
signed main(){
	cin>>n;
	int x;
	while(n--){
		cin>>op;
		if(op==1){
			cin>>x;
			last++;
			q[last]=x;	
		}
		if(op==2){
			if(last-front==0){
				cout<<"ERR_CANNOT_POP"<<endl;
			}
			else front++;
		}
		if(op==3){
			if(last-front==0){
				cout<<"ERR_CANNOT_QUERY"<<endl;
			}
			else cout<<q[front+1]<<endl;
		}
		if(op==4){
			cout<<last-front<<endl;
		}
	}
}

快速幂

快速幂
#include<bits/stdc++.h>
using namespace std;
long long a,b,c;
long long qpow(long long x,long long y){
	if(y==0)
	return 1;
	long long ans=1;
	while(y!=0){
		if(y&1){
			ans=(ans%c*x%c)%c;
		}
		x=(x%c*x%c)%c;
		y=y>>1;
	}
	ans=ans%c;
	return ans;
}
int main(){
	cin>>a>>b>>c;
	long long ans=qpow(a,b);
	ans=(ans+c)%c;
	cout<<a<<"^"<<b<<" "<<"mod"<<" "<<c<<"="<<ans;
} 

并查集

并查集
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
int f[maxn];
int getfa(int x){
	if(f[x]==x)
	return x;
	else{
		f[x]=getfa(f[x]);
		return f[x];
	}
}
int n,m;
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		f[i]=i;
	}
	for(int i=1;i<=m;i++){
		int op,x,y;
		cin>>op>>x>>y;
		if(op==1){
			f[getfa(x)]=getfa(y);
		}
		else{
			if(getfa(x)==getfa(y)){
				cout<<"Y"<<endl;
			}
			else{
				cout<<"N"<<endl;
			}
		}
	}
	return 0;
}

筛法求素数

欧拉筛
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e8+10;
bool flag[maxn];
int n,q,cnt;
int num[6000010];
signed main(){
	std::ios::sync_with_stdio(0);
	cin>>n>>q;
	for(int i=2;i<=n;i++){
		if(!flag[i]){
			cnt++;
			num[cnt]=i;	
		}
		for(int j=1;j<=cnt&&i*num[j]<=n;j++){
			flag[i*num[j]]=true;
			if(i%num[j]==0){
				break;
			}
		}
	}
	while(q--){
		int x;
		cin>>x;
		cout<<num[x]<<endl;
	}
	return 0;
}

双端队列

list版本
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
list<int>arr[maxn];
int q;
string s1;
signed main(){
	cin>>q;
	while(q--){
		cin>>s1;
		if(s1=="push_back"){
			int x,y;
			cin>>x>>y;
			arr[x].push_back(y);
		}
		else if(s1=="pop_back"){
			int x;
			cin>>x;
			if(arr[x].size()==0)
			continue;
			arr[x].pop_back();
		}
		else if(s1=="push_front"){
			int x,y;
			cin>>x>>y;
			arr[x].push_front(y);
		}
		else if(s1=="pop_front"){
			int x;
			cin>>x;
			if(arr[x].size()==0)
			continue;
			arr[x].pop_front();
		}
		else if(s1=="size"){
			int x;
			cin>>x;
			cout<<arr[x].size()<<endl;
		}
		else if(s1=="front"){
			int x;
			cin>>x;
			if(arr[x].size()==0)
			continue;
			cout<<arr[x].front()<<endl;
		}
		else if(s1=="back"){
			int x;
			cin>>x;
			if(arr[x].size()==0)
			continue;
			cout<<arr[x].back()<<endl;
		}
	}
	return 0;
}

哈希

单哈希
#include<bits/stdc++.h>
#define ull unsigned long long
#define int long long
using namespace std;
const int base=13131,maxn=1e6+10;
ull site[maxn];
map<int,int>mp;
int n,ans=0;
signed main(){
	cin>>n;
	site[0]=1;
	for(int i=1;i<=maxn;i++){
		site[i]=site[i-1]*base;
	}
	string s1;
	for(int i=1;i<=n;i++){
		cin>>s1;
		ull turn=0;
		for(int i=0;i<s1.size();i++){
			int num=(s1[i]-'a'+1);
			turn+=site[i+1]*num;	
		}
		if(!mp[turn]){
				ans++;
				mp[turn]++;
		}
	}
	cout<<ans;
	return 0;
}
双哈希
#include<bits/stdc++.h>
#define ull unsigned long long
#define int long long
using namespace std;
const int base1=13131,base2=13331,maxn=1e6+10;
ull site1[maxn],site2[maxn];
map<pair<int,int>,int>mp;
int n,ans=0;
signed main(){
	cin>>n;
	site1[0]=1;
	site2[0]=1;
	for(int i=1;i<=maxn;i++){
		site1[i]=site1[i-1]*base1;
		site2[i]=site2[i-1]*base2;
	}
	string s1;
	for(int i=1;i<=n;i++){
		cin>>s1;
		ull turn1=0,turn2=0;
		for(int i=0;i<s1.size();i++){
			int num=(s1[i]-'a'+1);
			turn1+=site1[i+1]*num;
			turn2+=site2[i+1]*num;
		}
		if(!mp[make_pair(turn1,turn2)]){
			ans++;
			mp[make_pair(turn1,turn2)]++;
		}
	}
	cout<<ans;
	return 0;
}
异或哈希
#include<bits/stdc++.h>
#define ull unsigned long long
#define int long long
using namespace std;
const int maxn=1e6+10;
ull site[maxn];
map<int,int>mp;
int n,ans=0;
signed main(){
	cin>>n;
	site[0]=1;
	std::mt19937_64 rnd(time(0));
	for(int i=1;i<=maxn;i++){
		site[i] = rnd();
	}
	string s1;
	for(int i=1;i<=n;i++){
		cin>>s1;
		ull turn=0;
		for(int i=0;i<s1.size();i++){
			int num=(s1[i]-'a'+1);
			turn^=site[i+1]*num;	
		}
		if(!mp[turn]){
			ans++;
			mp[turn]++;
		}
	}
	cout<<ans;
	return 0;
}

树的直径和直径中点

dfs版本
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e5+10;
int n,q;
struct edge{
	int next,to;
}e[maxn<<1];
int head[maxn],cnt;
void add(int x,int y){
	e[++cnt].next=head[x];
	e[cnt].to=y;
	head[x]=cnt;
}
int dep[maxn],maxx=0,maxi=0;
int father[maxn],node;
void dfs(int x,int fa){
	dep[x]=dep[fa]+1;
	father[x]=fa;
	if(dep[x]>maxx){
		maxx=dep[x];
		maxi=x;
	}
	for(int i=head[x];i;i=e[i].next){
		int v=e[i].to;
		if(v==fa)
		continue;
		dfs(v,x);
	}
}
void getmid(int x,int mid){
	if(dep[x]==mid){
		node=x;
		return;
	}
	else{
		getmid(father[x],mid);
	}
}
signed main(){
	freopen("tree.in","r",stdin);
	freopen("tree.out","w",stdout);
	cin>>n>>q;
	for(int i=1;i<n;i++){
		int x,y;
		cin>>x>>y;
		add(x,y);
		add(y,x);
	}
	dfs(1,0);
	dfs(maxi,0);
	if(maxx%2!=0)
	getmid(maxi,maxx/2+1);
	else node=0;
	return 0;
}

最小生成树

Kruskal
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000100;
int n,m,sma=0,tot=0;
int fa[maxn];
bool flag=true;
struct edge{
	int from;
	int to;
	int w;
}e[maxn];
inline bool cmp(edge x,edge y){
	return x.w<y.w;
}
int getfa(int x){
    if(fa[x]==x)
       return x;
    else
       return fa[x]=getfa(fa[x]);
}
void solve(){
	tot=0;
	sort(e+1,e+m+1,cmp);
	for(int i=1;i<=n;i++){
		fa[i]=i;
	}
	for(int i=1;i<=m;i++){
		int x=e[i].from,y=e[i].to;
		if(getfa(x)!=getfa(y)){
			fa[getfa(x)]=getfa(y);
			sma+=e[i].w;
			tot++;
			if(tot==n-1)
			break;
		}
	}
	if(tot!=n-1){
		cout<<"NO"<<endl;
		flag=false;
	}
}
int main(){
	flag=true;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>e[i].from>>e[i].to>>e[i].w;
	}
	solve();
	if(false){
		return 0;
	}
	else{
		cout<<sma<<endl;
	}
	return 0;
}
Prim
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
int n,m;
struct edge{
	int next,to,val;
}e[maxn<<1];
int head[maxn],cnt;
struct s{
	int u,d;
};
bool operator<(const s &x,const s &y){
	return x.d>y.d;
}
priority_queue<s> q;
int dis[maxn];
bool vis[maxn];
int res=0,tot=0;
void prim(){
	memset(dis,0x3f,sizeof(dis));
	dis[1]=0;
	q.push({1,0});
	while(!q.empty()){
		if(tot>=n)
		break;
		int u=q.top().u;
		int d=q.top().d;
		q.pop();
		if(vis[u]){
			continue;
		}
		vis[u]=true;
		++tot;
		res+=d;
		for(int i=head[u];i;i=e[i].next){
			int v=e[i].to;
			int w=e[i].val;
			if(w<dis[v]){
				dis[v]=w;
				q.push({v,w});
			}
		}
	}
}
void add(int x,int y,int w){
	e[++cnt].next=head[x];
	e[cnt].to=y;
	e[cnt].val=w;
	head[x]=cnt;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin>>x>>y>>z;
		add(x,y,z);
		add(y,x,z);
	}
	prim();
	if(tot==n){
		cout<<res;
	}
	else{
		cout<<"No";
	}
}

拓扑排序

拓扑排序
#include<bits/stdc++.h>
using namespace std;
bool g[110][110];
int in[110];
int n;
queue<int> q;
void toposort(){
	for(int i=1;i<=n;i++){
		if(in[i]==0)
		q.push(i);
	}
	while(!q.empty()){
		int x=q.front();
		cout<<x<<" ";
		q.pop();
		for(int i=1;i<=n;i++){
			if(g[x][i]){
				in[i]--;
				if(in[i]==0)
				q.push(i);
			}
			
		}
	}
}
int main(){
	memset(g,false,sizeof(g));
	memset(in,0,sizeof(in));
	cin>>n;
	int e;
	for(int i=1;i<=n;i++){
		while(cin>>e){
			if(e!=0){
				g[i][e]=true;
				in[e]++;
				continue;
			}
			else break;
		}
	}
	toposort();
	return 0;
}

KMP

KMP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
char s1[maxn],s2[maxn];
int len1,len2;
int kmp[maxn];
signed main(){
	cin>>s1+1;
	cin>>s2+1;
	len1=strlen(s1+1);
	len2=strlen(s2+1);
	int j=0;
	for(int i=2;i<=len2;i++){
		while(j&&s2[i]!=s2[j+1]){
			j=kmp[j];
		}
		if(s2[j+1]==s2[i]){
			j++;
		}
		kmp[i]=j;
	}
	j=0;
	for(int i=1;i<=len1;i++){
		while(j>0&&s2[j+1]!=s1[i]){
			j=kmp[j];
		}
		if(s2[j+1]==s1[i]){
			j++;
		}
		if(j==len2){
			cout<<i-len2+1<<endl;
			j=kmp[j];
		}
	}
	for(int i=1;i<=len2;i++){
		cout<<kmp[i]<<" ";
	}
	return 0;
}

判断负环(spfa)

spfa
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=6e3+10;
struct edge{
	int next,to,val;
}e[maxn];
int head[maxn],cnt;
queue<int>q;
int dis[maxn],num[maxn];
bool vis[maxn];
int t,n,m;
void add(int x,int y,int w){
	e[++cnt].next=head[x];
	e[cnt].to=y;
	e[cnt].val=w;
	head[x]=cnt;
}
bool spfa(){
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	memset(num,0,sizeof(num));
	dis[1]=0;
	vis[1]=true;
	q.push(1);
	while(!q.empty()){
		int f=q.front();
		q.pop();
		vis[f]=false;
		for(int i=head[f];i;i=e[i].next){
			int v=e[i].to;
			int w=e[i].val;
			if(dis[v]>dis[f]+w){
				dis[v]=dis[f]+w;
				num[v]=num[f]+1;
				if(num[v]>=n)
				return true;
				if(!vis[v]){
					q.push(v);
					vis[v]=true;
				}
			}
		}
	}
	return false;
}
signed main(){
	cin>>t;
	while(t--){
		for(int i=0;i<maxn;i++){
			e[i].next=0;
			head[i]=0;
		}
		cnt=0;
		cin>>n>>m;
		for(int i=1;i<=m;i++){
			int u,v,w;
			cin>>u>>v>>w;
			add(u,v,w);
			if(w>=0)
			add(v,u,w);
		}
		if(spfa()){
			cout<<"YES"<<endl;
		}
		else{
			cout<<"NO"<<endl;
		}
	}
	return 0;
}

单调栈

单调栈
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e6+10;
int arr[maxn],ans[maxn];
stack<int> s;
int n;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>arr[i];
		while(!s.empty()&&arr[i]>arr[s.top()]){
			ans[s.top()]=i;
			s.pop();
		}
		s.push(i);
	}
	for(int i=1;i<=n;i++){
		cout<<ans[i]<<" ";
	}
}

线段树

单点修改 区间查询
#include<bits/stdc++.h>
#define lid (id<<1)
#define rid ((id<<1)+1)
using namespace std;
const int maxn=3e6+10;
struct tree{
	int sum;
	int maxx;
	int lazy;
}tr[maxn];
int arr[maxn];
int n,q;
void build(int id,int l,int r){
	if(l==r){
		tr[id].maxx=arr[l];
		tr[id].sum=arr[l];
	}
	int mid=(l+r)/2;
	build(lid,l,mid);
	build(rid,mid+1,r);
	tr[id].maxx=max(tr[lid].maxx,tr[rid].maxx);
	tr[id].sum=tr[lid].sum+tr[rid].sum;
}
int query_sum(int id,int l,int r,int x,int y){
	if(x<=l&&r<=y){
		return tr[id].sum;
	}
	int mid=(l+r)/2,ans=0;
	if(x<=mid){
		ans+=query_sum(lid,l,mid,x,y);
	}
	if(y>mid){
		ans+=query_sum(rid,mid+1,r,x,y);
	}
	return ans;
}
int query_max(int id,int l,int r,int x,int y){
	if(x<=l&&r<=y){
		return tr[id].maxx;
	}
	int mid=(l+r)/2,ans=0;
	if(x<=mid){
		ans=max(ans,query_sum(lid,l,mid,x,y));
	}
	if(y>mid){
		ans=max(ans,query_sum(rid,mid+1,r,x,y));
	}
	return ans;
}
void change(int id,int l,int r,int x,int v){
	if(l==r){
		tr[id].maxx=v;
		tr[id].sum=v;
		return;
	}
	int mid=(l+r)/2;
	if(x<=mid)change(lid,l,mid,x,v);
	else change(rid,mid+1,r,x,v);
	tr[id].maxx=max(tr[lid].maxx,tr[rid].maxx);
	tr[id].sum=tr[lid].sum+tr[rid].sum;
}
int main(){
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		cin>>arr[i];
	}
	build(1,1,n);
	int flag;
	while(q--){
		cin>>flag;
		if(flag==1){
			int x,y;
			cin>>x>>y;
			change(1,1,n,x,y);
		}
		else{
			int x,y;
			cin>>x>>y;
			cout<<query_max(1,1,n,x,y)<<" "<<query_sum(1,1,n,x,y);
		}
	}
}
区间修改 区间查询
#include<bits/stdc++.h>
#define int long long
#define lid (id*2)
#define rid ((id*2)+1)
using namespace std;
const int maxn=1e5+10;
struct tree{
	int sum;
	int lazy;
}tr[maxn<<2];
int arr[maxn];
int n,q;
void push_up(int id){
	tr[id].sum=tr[lid].sum+tr[rid].sum;
}
void push_down(int id,int l,int r){
	if(tr[id].lazy){
		int mid=(l+r)/2;
		tr[lid].lazy+=tr[id].lazy;
		tr[rid].lazy+=tr[id].lazy;
		tr[lid].sum+=tr[id].lazy*(mid-l+1);
		tr[rid].sum+=tr[id].lazy*(r-mid);
		tr[id].lazy=0;
	}
}
void update(int id,int l,int r,int x,int y,int v){
	if(l>=x&&r<=y){
		tr[id].lazy+=v;
		tr[id].sum+=v*(r-l+1);
		return;
	}
	push_down(id,l,r);
	int mid=(l+r)/2;
	if(x<=mid){
		update(lid,l,mid,x,y,v);
	}
	if(y>mid){
		update(rid,mid+1,r,x,y,v);
	}
	push_up(id);
}
int query(int id,int l,int r,int x,int y){
	if(l>=x&&r<=y){
		return tr[id].sum;
	}
	push_down(id,l,r);
	int mid=(l+r)/2,ans=0;
	if(x<=mid) ans+=query(lid,l,mid,x,y);
	if(y>mid) ans+=query(rid,mid+1,r,x,y);
	return ans;
}
void build(int id,int l,int r){
	if(l==r){
		tr[id].sum=arr[l];
		return;
	}
	int mid=(l+r)/2;
	build(lid,l,mid);
	build(rid,mid+1,r);
	tr[id].sum=tr[lid].sum+tr[rid].sum;
}
signed main(){
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		cin>>arr[i];
	}
	build(1,1,n);
	int flag;
	while(q--){
		cin>>flag;
		if(flag==1){
			int x,y,z;
			cin>>x>>y>>z;
			update(1,1,n,x,y,z);
		}
		else{
			int x,y;
			cin>>x>>y;
			cout<<query(1,1,n,x,y)<<endl;
		}
	}
	return 0;
}
区间修改 区间查询pro
#include<bits/stdc++.h>
#define int long long
#define lid (id<<1)
#define rid ((id<<1)+1)
using namespace std;
const int maxn=1e5+10;
int n,m,mod;
int arr[maxn];
struct tree{
	int sum,mul,add;
}tr[maxn<<2];
void push_up(int id){
	tr[id].sum=(tr[lid].sum+tr[rid].sum)%mod;
}
void build(int id,int l,int r){
	tr[id].mul=1;
	tr[id].add=0;
	if(l==r){
		tr[id].sum=arr[l];
		tr[id].sum%=mod;
		return;
	}
	int mid=(l+r)/2;
	build(lid,l,mid);
	build(rid,mid+1,r);
	push_up(id);
	tr[id].sum%=mod;
	return;
}
void push_down(int id,int l,int r){
	int mid=(l+r)/2;
	tr[lid].sum=(tr[lid].sum*tr[id].mul+(mid-l+1)*tr[id].add)%mod;
	tr[rid].sum=(tr[rid].sum*tr[id].mul+(r-mid)*tr[id].add)%mod;
	tr[lid].mul=(tr[lid].mul*tr[id].mul)%mod;
	tr[rid].mul=(tr[rid].mul*tr[id].mul)%mod;
	tr[lid].add=(tr[lid].add*tr[id].mul+tr[id].add)%mod;
	tr[rid].add=(tr[rid].add*tr[id].mul+tr[id].add)%mod;
	tr[id].add=0;
	tr[id].mul=1;
	return;
}
void update1(int id,int l,int r,int x,int y,int v){
	if(x<=l&&y>=r){
		tr[id].sum=(tr[id].sum*v)%mod;
		tr[id].mul=(tr[id].mul*v)%mod;
		tr[id].add=(tr[id].add*v)%mod;
		return;
	}
	push_down(id,l,r);
	int mid=(l+r)/2;
	if(x<=mid){
		update1(lid,l,mid,x,y,v);
	}
	if(y>mid){
		update1(rid,mid+1,r,x,y,v);
	}
	push_up(id);
	return;
}
void update2(int id,int l,int r,int x,int y,int v){
	if(x<=l&&y>=r){
		tr[id].sum=(tr[id].sum+v*(r-l+1))%mod;
		tr[id].add=(tr[id].add+v)%mod;
		return;
	}
	push_down(id,l,r);
	int mid=(l+r)/2;
	if(x<=mid){
		update2(lid,l,mid,x,y,v);
	}
	if(y>mid){
		update2(rid,mid+1,r,x,y,v);
	}
	push_up(id);
	return;
}
int query(int id,int l,int r,int x,int y){
	if(y<l||r<x){
		return 0;
	}
	if(x<=l&&y>=r){
		return tr[id].sum;
	}
	push_down(id,l,r);
	int mid=(l+r)/2;
	return (query(lid,l,mid,x,y)+query(rid,mid+1,r,x,y))%mod;
}
signed main(){
	cin>>n>>m>>mod;
	for(int i=1;i<=n;i++){
		cin>>arr[i];
	}
	build(1,1,n);
	int flag,x,y,z;
	while(m--){
		cin>>flag;
		if(flag==1){
			cin>>x>>y>>z;
			update1(1,1,n,x,y,z);
		}
		else if(flag==2){
			cin>>x>>y>>z;
			update2(1,1,n,x,y,z);
		}
		else{
			cin>>x>>y;
			cout<<query(1,1,n,x,y)<<'\n';
		}
	}
}	

传递闭包

传递闭包
#include<bits/stdc++.h>
using namespace std;
int n;
bitset<110>a[110];
int main(){
	cin>>n;
	int x;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cin>>x;
			if(x)
			a[i][j]=true;
			else
			a[i][j]=false;
		}
	}
	for(int j=1;j<=n;j++){
		for(int i=1;i<=n;i++){
			if(a[i][j]){
				a[i]|=a[j];
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(a[i][j]){
				cout<<1<<" ";
			}
			else{
				cout<<0<<" ";
			}
		}
		cout<<'\n';
	}
}

裴蜀定理

裴蜀定理
#include<bits/stdc++.h>
using namespace std;
const int maxn=25;
int n;
int arr[maxn];
int gcd(int x,int y){
	return y?gcd(y,x%y):x;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>arr[i];
		if(arr[i]<0){
			arr[i]=-arr[i];
		}
	}
	for(int i=1;i<n;i++){
		arr[i+1]=gcd(arr[i+1],arr[i]);
	}
	cout<<arr[n];
}

树状数组

单点修改 区间查询
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
int c[maxn],arr[maxn];
int n,m;
int lowbit(int x){
	return x&-x;
}
void update(int x,int val){
	while(x<=n){
		c[x]+=val;
		x+=lowbit(x);
	}
}
int query(int x){
	int ans=0;
	while(x>0){
		ans+=c[x];
		x-=lowbit(x);	
	}
	return ans;
}
int check(int l,int r){
	return query(r)-query(l-1);
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>arr[i];
		update(i,arr[i]);
	}
	for(int i=1;i<=m;i++){
		int flag,x,y;
		cin>>flag>>x>>y;
		if(flag==1){
			update(x,y);
		}
		else{
			cout<<check(x,y)<<endl;
		}
	}
	return 0;
}
区间修改 单点查询
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
int c[maxn],arr[maxn];
int n,m;
int lowbit(int x){
	return x&-x;
}
void insert(int x,int val){
	while(x<=n){
		c[x]+=val;
		x+=lowbit(x);
	}
}
void update(int x,int y,int val){
	insert(x,val);
	insert(y+1,-val);
}
int query(int x){
	int ans=0;
	while(x>0){
		ans+=c[x];
		x-=lowbit(x);	
	}
	return ans;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>arr[i];
		update(i,i,arr[i]);
	}
	for(int i=1;i<=m;i++){
		int flag,x,y,z;
		cin>>flag>>x;
		if(flag==1){
			cin>>y>>z;
			update(x,y,z);
		}
		else{
			cout<<query(x)<<endl;
		}
	}
	return 0;
}

矩阵快速幂

矩阵快速幂
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7;
struct matrix{
	int c[110][110];
}arr,base;
int n,k;
matrix operator*(const matrix &x,const matrix &y){
	matrix a;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			a.c[i][j]=0;
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			for(int k=1;k<=n;k++){
				a.c[i][j]+=x.c[i][k]*y.c[k][j]%mod;
				a.c[i][j]%=mod;
			}
		}
	}
	return a;
}
void qpow(matrix &a,int &b){
	while(b>0){
		if(b%2==1){
			base=base*a;
		}
		a=a*a;
		b=b>>1;
	}
}
signed main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cin>>arr.c[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		base.c[i][i]=1;
	}
	qpow(arr,k);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cout<<base.c[i][j]<<" ";
		}
		cout<<endl;
	}
}

LCA

倍增
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
int n,m,s;
struct edge{
	int next,to;
}e[maxn<<1];
int head[maxn],cnt;
int dep[maxn],fa[maxn][22];
void add(int x,int y){
	e[++cnt].next=head[x];
	e[cnt].to=y;
	head[x]=cnt;
}
void dfs(int u,int f){
	dep[u]=dep[f]+1;
	fa[u][0]=f;
	for(int i=1;(1<<i)<=dep[u];i++){
		fa[u][i]=fa[fa[u][i-1]][i-1];
	}
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].to;
		if(v==f)
		continue;
		dfs(v,u);
	}
}
int lca(int a,int b){
	if(dep[a]>dep[b]){
		swap(a,b);
	}
	for(int i=20;i>=0;i--){
		if(dep[a]<=dep[b]-(1<<i)){
			b=fa[b][i];
		}
	}
	if(a==b)return a;
	for(int i=20;i>=0;i--){
		if(fa[a][i]==fa[b][i]){
			continue;
		}
		else{
			a=fa[a][i],b=fa[b][i];
		}	
	}
	return fa[a][0];
}
int main(){
	cin>>n>>m>>s;
	int u,v;
	for(int i=1;i<n;i++){
		cin>>u>>v;
		add(u,v);
		add(v,u);
	}
	dfs(s,0);
	for(int i=1;i<=m;i++){
		cin>>u>>v;
		cout<<(lca(u,v))<<endl;
	}
	return 0;
}
dfs序
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
int n,m,s;
struct edge{
	int next,to;
}e[maxn<<1];
int head[maxn],cnt;
int dfn[maxn],mi[19][maxn],dn;
void add(int x,int y){
	e[++cnt].next=head[x];
	e[cnt].to=y;
	head[x]=cnt;
}
int get(int x,int y){
	return dfn[x]<dfn[y]?x:y;
}
void dfs(int u,int f){
	mi[0][dfn[u]=++dn]=f;
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].to;
		if(v==f)
		continue;
		dfs(v,u);
	}
}
int lca(int a,int b){
	if(a==b)return a;
	if((a=dfn[a])>(b=dfn[b])){
		swap(a,b);
	}
	int d=__lg(b-a++);
	return get(mi[d][a],mi[d][b-(1<<d)+1]);
}
int main(){
	cin>>n>>m>>s;
	int u,v;
	for(int i=1;i<n;i++){
		cin>>u>>v;
		add(u,v);
		add(v,u);
	}
	dfs(s,0);
	for(int i=1;i<=__lg(n);i++){
		for(int j=1;j+(1<<i)-1<=n;j++){
			mi[i][j]=get(mi[i-1][j],mi[i-1][j+(1<<i-1)]);
		}
	}
	for(int i=1;i<=m;i++){
		cin>>u>>v;
		cout<<(lca(u,v))<<endl;
	}
	return 0;
}
树链剖分
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
int n,m,s;
struct edge{
	int next,to;
}e[maxn<<1];
int head[maxn],cnt;
int dep[maxn],siz[maxn],son[maxn],top[maxn],fa[maxn];
void add(int x,int y){
	e[++cnt].next=head[x];
	e[cnt].to=y;
	head[x]=cnt;
}
void dfs1(int u,int f){
	siz[u]=1;
	dep[u]=dep[f]+1;
	fa[u]=f;
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].to;
		if(v==f)
		continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(!son[u]||siz[son[u]]<siz[v]){
			son[u]=v;
		}
	}
}
void dfs2(int u,int t){
	top[u]=t;
	if(son[u]){
		dfs2(son[u],t);
	}
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].to;
		if(v==fa[u]||v==son[u])
		continue;
		dfs2(v,v);
	}
}
int lca(int u,int v){
	while(top[u]!=top[v]){
		if(dep[top[u]]>=dep[top[v]]){
			u=fa[top[u]];
		}
		else{
			v=fa[top[v]];
		}
	}
	return dep[u]<dep[v]?u:v;
}
int main(){
	cin>>n>>m>>s;
	int u,v;
	for(int i=1;i<n;i++){
		cin>>u>>v;
		add(u,v);
		add(v,u);
	}
	dfs1(s,0);
	dfs2(s,s);
	for(int i=1;i<=m;i++){
		cin>>u>>v;
		cout<<lca(u,v)<<endl;
	}
	return 0;
}

Dijkstra

堆优化Dijkstra
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int INF=2147483647;
const int maxn=5e5+10;
int n,m,s;
int dis[maxn];
struct edge{
	int next,to,val;
}e[maxn<<1];
struct node{
	int s,w;
	bool operator<(const node &t)const{
		return t.w<w;
	} 
};
int head[maxn],cnt;
void add(int u,int v,int w){
	e[++cnt].next=head[u];
	e[cnt].to=v;
	e[cnt].val=w;
	head[u]=cnt;
}
void dijkstra(int x){
	priority_queue<node> q;
	dis[x]=0;
	q.push({x,0});
	while(!q.empty()){
		node t=q.top();
		q.pop();
		if(dis[t.s]<t.w)
		continue;
		for(int i=head[t.s];i;i=e[i].next){
			int v=e[i].to;
			if(dis[v]>e[i].val+t.w){
				dis[v]=e[i].val+t.w;
				q.push({v,dis[v]});
			}
		}
	}
}
signed main(){
	cin>>n>>m>>s;
	int u,v,w;
	for(int i=1;i<=m;i++){
		cin>>u>>v>>w;
		add(u,v,w);
	}
	for(int i=1;i<=n;i++){
		dis[i]=INF;
	}
	dijkstra(s);
	for(int i=1;i<=n;i++){
		cout<<dis[i]<<" ";
	}
}

tarian缩点

缩点
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+10;
int n,m,cnt,tim,top,s;
int p[maxn],head[maxn],sd[maxn],dfn[maxn],low[maxn];
int stac[maxn];
bool vis[maxn];
int h[maxn],in[maxn],dist[maxn];
struct Edge{
	int to,next,from;
}edge[maxn*10],ed[maxn*10];
void add(int x,int y){
	edge[++cnt].next=head[x];
	edge[cnt].from=x;
	edge[cnt].to=y;
	head[x]=cnt;
}
void tarjan(int x){
	low[x]=dfn[x]=++tim;
	stac[++top]=x;
	vis[x]=true;
	for(int i=head[x];i;i=edge[i].next){
		int v=edge[i].to;
		if(!dfn[v]){
			tarjan(v);
			low[x]=min(low[x],low[v]);
		}
		else if(vis[v]){
			low[x]=min(low[x],low[v]);
		}
	}
	if(dfn[x]==low[x]){
			int y;
			while(y=stac[top--]){
				sd[y]=x;
				vis[y]=false;
				if(x==y)break;
				p[x]+=p[y];
			}
		}	
}
int topo(){
	queue<int>q;
	int tot=0;
	for(int i=1;i<=n;i++){
		if(sd[i]==i&&!in[i]){
			q.push(i);
			dist[i]=p[i];
		}
	}
	while(!q.empty()){
		int k=q.front();
		q.pop();
		for(int i=h[k];i;i=ed[i].next){
			int v=ed[i].to;
			dist[v]=max(dist[v],dist[k]+p[v]);
			in[v]--;
			if(in[v]==0){
				q.push(v);
			}
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		ans=max(ans,dist[i]);
	}
	return ans;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>p[i];
	}
	for(int i=1;i<=m;i++){
		int u,v;
		cin>>u>>v;
		add(u,v);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i]){
			tarjan(i);
		}
	}
	for(int i=1;i<=m;i++){
		int x=sd[edge[i].from];
		int y=sd[edge[i].to];
		if(x!=y){
			ed[++s].next=h[x];
			ed[s].to=y;
			ed[s].from=x;
			h[x]=s;
			in[y]++;
		}
	}
	cout<<topo();
	return 0;
}

## nim游戏

<details>
<summary>nim游戏</summary>

```cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		int ans=0;
		for(int i=1;i<=n;i++){
			int a;
			cin>>a;
			ans^=a;
		}
		if(ans==0){
			cout<<"No"<<endl;
		}
		else cout<<"Yes"<<endl;
	}
	return 0;
}

欧拉路径

欧拉路径
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int n,m,del[maxn],cnt[2],beg=1;
int line[maxn][2];
stack<int>s;
vector<int>e[maxn];
void dfs(int now){
	for(int i=del[now];i<e[now].size();i=del[now]){
		del[now]=i+1;
		dfs(e[now][i]);
	}
	s.push(now);
}
int main(){
	cin>>n>>m;
	int u,v; 
	for(int i=1;i<=m;i++){
		cin>>u>>v;
		e[u].push_back(v);
		line[u][1]++;
		line[v][0]++;
	}
	for(int i=1;i<=n;i++){
		sort(e[i].begin(),e[i].end());
	}
	bool flag=true;
	for(int i=1;i<=n;i++){
		if(line[i][1]!=line[i][0]){
			flag=false;
			if(line[i][1]-line[i][0]==1){
				cnt[1]++;
				beg=i;
			}
			else if(line[i][0]-line[i][1]==1){
				cnt[0]++;
			}
			else{
				cout<<"No";
				return 0;
			}
		}
	}
	if((!flag)&&!(cnt[0]==cnt[1]&&cnt[0]==1)){
		cout<<"No";
		return 0;
	}
	dfs(beg);
	while(!s.empty()){
		cout<<s.top()<<" ";
		s.pop();
	}
	return 0;
}

康托展开

康托展开
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+10;
const int mod=998244353;
int n;
int arr[maxn],c[maxn],lowbit[maxn];
int fac[maxn],ans;
void add(int x,int k){
	while(x<=n){
		c[x]+=k;
		x+=lowbit[x];
	}
}
int sum(int x){
	int t=0;
	while(x>0){
		t+=c[x];
		x-=lowbit[x];
	}
	return t;
}
signed main(){
	cin>>n;
	fac[0]=1;
	for(int i=1;i<n;i++){
		fac[i]=fac[i-1]*i%mod;
		lowbit[i]=i&-i;
	}
	lowbit[n]=n&-n;
	for(int i=1;i<=n;i++){
		add(i,1);
	}
	for(int i=1;i<=n;i++){
		cin>>arr[i];
		ans=(ans+((sum(arr[i])-1)*fac[n-i])%mod)%mod;
		add(arr[i],-1);
	}
	cout<<ans+1;
	return 0;
}	

差分约束

差分约束
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int INF=2e9;
const int maxn=3e5+10;
int n,m;
int dis[maxn],num[maxn];
bool vis[maxn];
struct edge{
	int next,to,val;
}e[maxn];
int head[maxn],cnt;
queue<int>q;
void add(int u,int v,int w){
	e[++cnt].next=head[u];
	e[cnt].to=v;
	e[cnt].val=w;
	head[u]=cnt;
}
bool spfa(int x){
	dis[x]=0;
	q.push(x);
	vis[x]=true;
	num[x]++;
	while(!q.empty()){
		int turn=q.front();
		q.pop();
		vis[turn]=false;
		for(int i=head[turn];i;i=e[i].next){
			int v=e[i].to;
			if(dis[v]>dis[turn]+e[i].val){
				dis[v]=dis[turn]+e[i].val;
				if(!vis[v]){
					q.push(v);
					vis[v]=true;
					num[v]++;
					if(num[v]==n+1){
						return false;
					}
				}
			}
		}
	}
	return true;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		dis[i]=INF;
	}
	int u,v,w;
	for(int i=1;i<=m;i++){
		cin>>u>>v>>w;
		add(v,u,w);
	}
	for(int i=1;i<=n;i++){
		add(n+1,i,0);
	}
	if(!spfa(n+1)){
		cout<<"NO";
		return 0;
	}
	for(int i=1;i<=n;i++){
		cout<<dis[i]<<" ";
	}
	return 0;
}

有理数取余

有理数取余
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=19260817;
int a,b,x,y;
inline int read(){
    int res=0,ch=getchar();
    while(!isdigit(ch)&&ch!=EOF)
        ch=getchar();
    while(isdigit(ch)){
        res=(res<<3)+(res<<1)+(ch-'0');
        res%=mod;
        ch=getchar();
    }
    return res;
}
void exgcd(int a,int b){
	if(b==0){
		x=1;
		y=0;
		return;
	}
	exgcd(b,a%b);
	int turn=x;
	x=y;
	y=turn-a/b*y;
}
signed main(){
	a=read();
	b=read();
	if(b==0){
		cout<<"Angry!";
		return 0;
	}
	exgcd(b,mod);
	x=(x%mod+mod)%mod;
	cout<<a*x%mod;
}

最长公共子序列

最长公共子序列
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e5+10;
int n;
int a[maxn],b[maxn],site[maxn],dp[maxn];
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		site[a[i]]=i;
	}
	for(int i=1;i<=n;i++){
		cin>>b[i];
		dp[i]=0x7fffffff;
	}
	int len=0;
	for(int i=1;i<=n;i++){
		int l=0,r=len,mid;
		if(site[b[i]]>dp[len]){
			dp[++len]=site[b[i]];
		}
		else{
			while(l<r){
				mid=(l+r)/2;
				if(dp[mid]>site[b[i]]){
					r=mid;
				}
				else{
					l=mid+1;
				}
			}
			dp[l]=min(dp[l],site[b[i]]);
		}
	}
	cout<<len;
	return 0;
}

manacher

manacher
#include<bits/stdc++.h>
using namespace std;
const int maxn=51000100;
char a[maxn],s[maxn];
int num[maxn];
int len,ans;
void turn(){
	s[0]=s[1]='#';
	for(int i=0;i<len;i++){
		s[i*2+2]=a[i];
		s[i*2+3]='#';
	}
	len=len*2+2;
	s[len]=0;
}
void manacher(){
	int maxr=0,mid;
	for(int i=1;i<len;i++){
		if(i<maxr){
			num[i]=min(num[(mid<<1)-i],num[mid]+mid-i);
		}
		else{
			num[i]=1;
		}
		for(;s[i+num[i]]==s[i-num[i]];++num[i]);
		if(num[i]+i>maxr){
			maxr=num[i]+i;
			mid=i;
		}
	}
}
int main(){
	cin>>a;
	len=strlen(a);
	turn();
	manacher();
	for(int i=0;i<len;i++){
		ans=max(ans,num[i]);
	}
	cout<<ans-1;
	return 0;
}
posted @ 2023-10-19 14:39  chancelong  阅读(31)  评论(3编辑  收藏  举报