#include<string.h>
#define MAX 10000
struct node
{
int to,nex,wei;
}edge[MAX*2+5];
int head[MAX+5],cnt;
void add(int u,int v,int w)//添加一个单向边u->v 权为w
{
edge[cnt].to=v;
edge[cnt].wei=w;
edge[cnt].nex=head[u];
head[u]=cnt++;
}
int main()
{
memset(head,-1,sizeof(head));//初始化为-1
cnt=0;//初始化 0
}
tarjan连通性
#include<stack>
#include<algorithm>
#include<string.h>
using namespace std;
stack<int>s;
int dfn[1000],low[1000],scc[1000];//dfn[]时间戳 low[]最浅到达的点的时间戳 scc[]属于第几个scc
int index;//时间戳
int sccnum;//强连通的序号&&数量
void tarjan(int t)
{
dfn[t]=low[t]=++index;//记录时间戳
s.push(t);//入栈
for(int i=head[t];~i;i=edge[i].nex)//遍历儿子
{
int v=edge[i].to;//v是儿子
if(!dfn[v])//如果没走过
{
tarjan(v);//向下递归
low[t]=min(low[t],low[v]);//更新为min(当前,儿子)
}
else if(!scc[v])//如果不在栈中
{
low[t]=min(low[t],dfn[v]);
}
}
if(low[t]==dfn[t])//出栈
{
sccnum++;
while(!s.empty())
{
int x=s.top();
scc[x]=sccnum;
s.pop();
if(x==t)//直到刚刚出去的和现在的一样
break;
}
}
}
int main()
{
index=0;
sccnum=0;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(scc,0,sizeof(scc));
//初始化
}
GCD&LCM
//最小公倍数 = a*b / 最大公因数
typedef long long ll;
ll GCD(ll a, ll b)
{
return b == 0 ? a : GCD(b, a%b);
}
ll lcm(ll a, ll b)
{
return (a / GCD(a, b)*b);
}
快速幂
const long long MOD=1000000007
int ppow(int a, int b)//a^b
{
int ans = 1;
while (b)
{
if (b & 1)
{
ans *= a;
ans %= MOD;
}
a*= a;
a%= MOD;
b >>= 1;
}
return ans;
}
并查集
int sset[100000 + 5];
//find=find_father 得到父亲
int find(int a)//x=find(a) 将x放入a的集合
{
if (sset[a] != a)
{
sset[a] = find(sset[a]);
}
return sset[a];
}
void merge(int a, int b)//合并a,b
{
sset[a] = b;
}
最长上升子序列(LIS)
int b[100000];
int LIS(int a[], int n) {
int len = 1; b[0] = a[0];
for (int i = 1; i < n; i++) {
b[a[i] > b[len - 1] ? len++ : lower_bound(b, b + len, a[i]) - b] = a[i]; //非降换为>=和upper_bound
}
return len;
}
大整数类
#pragma once
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<vector>
using namespace std;
struct BigInteger {
static const int BASE = 10;
static const int WIDTH =1;
vector<int> s;
BigInteger(long long num = 0) { *this = num; } // 构造函数
BigInteger operator = (long long num)
{ // 赋值运算符
s.clear();
do
{
s.push_back(num % BASE);
num /= BASE;
} while (num > 0);
return *this;
}
BigInteger operator = (const string& str)
{ // 赋值运算符
s.clear();
int x, len = (str.length() - 1) / WIDTH + 1;
for (int i = 0; i < len; i++)
{
int end = str.length() - i*WIDTH;
int start = max(0, end - WIDTH);
sscanf(str.substr(start, end - start).c_str(), "%d", &x);
s.push_back(x);
}
return *this;
}
BigInteger operator + (const BigInteger& b) const
{
BigInteger c;
c.s.clear();
for (int i = 0, g = 0; ; i++)
{
if (g == 0 && i >= s.size() && i >= b.s.size()) break;
int x = g;
if (i < s.size()) x += s[i];
if (i < b.s.size()) x += b.s[i];
c.s.push_back(x % BASE);
g = x / BASE;
}
return c;
}
BigInteger operator * (const BigInteger& b)const
{
BigInteger c,t;
c = 0;
for (int i = 0; i<s.size(); i++)
{
t.s.clear();
long long x,g;
int j;
j = i;
while (j--)
t.s.push_back(0);
for (j=g=0; ; j++)
{
if (j >= b.s.size() && g == 0) break;
x = g;
if(j<b.s.size()) x += s[i] * b.s[j];
t.s.push_back(x%BASE);
g = x / BASE;
}
c += t;
}
return c;
}
BigInteger operator +=(const BigInteger& b)
{
*this = *this + b;
return *this;
}
bool operator<(const BigInteger& b)const
{
if (s.size() != b.s.size())
return s.size() < b.s.size();
for (int i = s.size() - 1; i >= 0; i--)
if (s[i] != b.s[i])
return s[i] < b.s[i];
return false;
}
bool operator >(const BigInteger& b)const { return b < *this; }
bool operator <=(const BigInteger& b)const { return !(b < *this); }
bool operator >=(const BigInteger& b)const { return !(*this < b); }
bool operator !=(const BigInteger& b)const { return b < *this || *this < b; }
bool operator ==(const BigInteger& b)const { return !(b < *this) && !(*this < b); }
};
ostream& operator << (ostream &out, const BigInteger& x)
{
out << x.s.back();
for (int i = x.s.size() - 2; i >= 0; i--)
{
char buf[20];
sprintf(buf, "%d", x.s[i]);
for (int j = 0; j < strlen(buf); j++) out << buf[j];
}
return out;
}
istream& operator >> (istream &in, BigInteger& x)
{
string s;
if (!(in >> s)) return in;
x = s;
return in;
}
树状数组
int c[100005];
int lowbit(int x)
{
return x & (-x);
}
void update(int x, int d)
{
while (x <= 100000)
{
c[x] = c[x] + d;
x = x + lowbit(x);
}
}
int getsum(int x)
{
int res = 0;
while (x > 0)
{
res = res + c[x];
x = x - lowbit(x);
}
return res;
}
O(N)素数筛法
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
const int MAX = 10000000;
bool isprime[MAX];//0true 1false
void getprime()
{
for (int i = 2; i <= MAX; i++)
{
for (int j = 2; j*i <= MAX; j++)
{
isprime[j*i] = 1;
if (!(i%j)) break;
}
}
}
int main()
{
getprime();
for (int i =2; i < 1000; i++)
{
if (isprime[i] == 0)
printf("%5d ", i);
}
}