奇奇怪怪的知识点/小技巧

位运算

异或

简介&简单性质

1、一个数异或自己为0,称为自反

异或的话其实可以看做不进位的加法

奇怪的用法

对于一个排列 0~ \(2^{n-1}\) 来说,我们可以找到\(2^{n-1}\)这个数并记为\(x\),让0~\(2^{n-1}-1\)的任一个数记为\(y_1\)\({y_1}\oplus{x}\)总是能得到\(y_1+x\)。让\(2^{n-1}\)+1 ~ \(2^{n-1}\)的任一个数记为\(y_2\)\({y_2}\oplus{x}\)总是能得到\(y_2-x\)

我们可以用x<<1|1 来表示 \({x*2+1}\)

状态压缩

当每件事情只有01两种状态的时候,我们可以用\({2^n}\)-1来枚举各种状态,比如在使用容斥原理的时候就可以使用

数论

关于质数

2是唯一的偶质数呢,并且我们可以知道一个数x可以用1到3个质数相加得到,这分别对应着的是质数的情况,偶数以及(x-2)为一个质数的情况, 除了前两种情况的情况。

组合数

预处理

当数据范围比较小的时候,预处理组合数的值可以直接使用递推式

\[{C_n^k = C_{n-1}^k + C_{n-1}^{k-1}} \]

公式

3.20校内排位赛的H题,习得对于组合数有以下公式

\[{\sum^n_{i=1}C^i_n*C^{k-i}_m = C^k_{n+m}} \]

字符串

构造

想要构造一个长度为d的0串并且命名为t可以直接这样写: string t(d, '0');

写法优化

scanf的特性

有些又要处理数字又要处理字符的题目,如果用scanf就可以免去处理字符类型转换到数字类型,比如说读入AM18:00,只需要

int main(){
    char c1, c2, c3;
    int hh, mm;
	//记得getchar
    int t;scanf("%d", &t);
    getchar();
    while(t--){
	//记得在前面加空格
        scanf(" %c%c%d%c%d", &c1, &c2, &hh, &c3, &mm);
        printf("%c%c%d%c%d\n", c1, c2, hh, c3, mm);
    }
    return 0;
}

数组切段

这样就能很好地实现了,而且比较短

void check(){
	_index.clear();
	for(int l = 1, r = 1;l <= n;l = r+1, r = l){
		while(r < n && (M[l] == M[r+1])) ++r;
		_index.push_back({l, r});
	}
}

匿名函数lambda

详细的介绍教程:
https://docs.microsoft.com/zh-cn/cpp/cpp/lambda-expressions-in-cpp?view=msvc-170
这样不会破坏写程序的连贯性

sort(s+l, s+r, [](const char&A, const char&B){
			return A>B;
		});


int main()
{
	[] {}();//三部分,[] : 代表lambda表达式的开始;{} : 代表函数体,函数体里面什么都没有;() : 代表函数调用.
}

开long long

直接这样

#define int long long;
signed main(){}

不过这样常数会很大,可能会被卡,慎重

判断

想要做到一旦有一个true它的后继状态都是true的话

(flag || (i == 1));

其中后面那个条件可以根据需求修改

换行

for(int i = 1;i <= 10;++i){
        for(int j = 1;j <= 5;++j){
			//这个地方是空格+\n
            cout << i*j << " \n"[j==5];
        }
    }

杂项/debug经验

!!

vsc经常自动帮优化哇,导致oj上输出和本地输出不一样,如果有迷wa的话不妨换成cb写吧!

TLE且时间复杂度没算错

1、代码哪里写错了位置!!(有次比赛昏头了把sort写错位置了de了好久都没发现T T)
2、数组越界

posted @ 2022-02-06 13:20  _77  阅读(96)  评论(0编辑  收藏  举报