本人在做题/阅读时的一点积累整理。
——Lrice
读入
1.需要读入数据量较大的情形,解除与scanf函数绑定,少用。
std::ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
2.文件操作,文本读入。
void fre(){
freopen("C:\\Users\\acm\\Desktop\\输入文本.txt", "r", stdin);
freopen("C:\\Users\\acm\\Desktop\\输出文本.txt", "w", stdout);
}
3.涉及换行符的单个字符读入。
char next;
cin.get(next);
while (next != '\n')cin.get(next);
公约数
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
} //最大公约数
lcm = a * b / gcd(a,b) //最小公倍数
位运算
1.快速幂
long pow_2(int b)
{
long x = 2;
long res = 1;
while (b > 0)
{
if (b & 1)
res *= x;
b >>= 1;
x = x * x;
}
return res;
}
long long Pow(long long a,long long n){
long long ret=1;
while(n){
if(n&1)ret*=a;
a*=a;
n>>=1;
}
return ret;
}
long long Mod_Pow(long long a,long long n,long long mod){
long long ret=1;
while(n){
if(n&1)ret=(ret*a)%mod;
a=(a*a)%mod;
n>>=1;
}
return ret;
}
2.集合的整数表示
空集:0
只含有第i个元素的集合:1 << i
含有全部元素:1 << N - 1
判断第i个元素是否属于集合S:if(S >> i & 1)
向集合中加入第i个元素:S | 1 << i
从集合中去除第i个元素:S & ~(1 << i)
集合S和集合T的并集:S | T
集合S和集合T的交集:S & T
转换
char->int
char s[100];
int x=atoi(s);
string->int
include<sstream>
void s2i(string &str,int &num)
{
stringstream ss;
ss<<str;
ss>>num;
}
并查集
int par[MAX_N];//父亲
int rank[MAX_N];//树的高度
//初始化n个元素
void init(int n)
{
for(int i=0;i<n;i++)
{
par[i]=i;
rank[i]=0;
}
}
//查询树的根
int find(int x)
{
if(par[x]==x)
return x;
else
return par[x]=find(par[x]);
}
//合并x和y所属的集合
void unite(int x,int y)
{
x = find(x);
y = find(y);
if (x == y)
return;
if (rank[x] < rank[y])
par[x] = y;
else
{
par[y] = x;
if (rank[x] == rank[y])
rank[x]++;
}
}
//判断x和y是否属于同一个集合
bool same(int x,int y)
{
return find(x)==find(y);
}