小寄巧
空间大小
分别在定义数组前、后加一个 bool
变量 st
和 ed
,输出 (&ed-&st)/1024./1024.
就是所开数组占用的空间(单位MiB)啦~
示例
bool st;
int n,k,ans;
int a[10000000];
bool ed;
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cout<<(&ed-&st)/1024./1024.;
return Elaina;
}
离散化
直接离散化的话可能会导致本不连续的值连续,有两种解决方法。
法一:
离散化的时候把每个值+1放到离散化数组里,这样原本不连续的数离散化后也不连续。
法二:
这种方法常数会小一些。
记录一下离散化数组中每个数是否和前一个数一样,如果离散化用的数组叫做 \(lsh\),先将 \(lsh\) 排序,令 \(dif_i=[lsh_i=lsh_{i-1}]\) ,求出 \(dif\) 的前缀和 \(blo_i\),那么 \(blo_i\) 相同的数就是在一个连续块里的。
令 \(f_i=[blo_{a_i}=blo_{a_{i-1}}]\)(也就是这一位是否和前一位在一个连续块里),再用一个树状数组维护 \(f\) 的前缀和,就可以快速查询一个区间内的所有值是否都在同一个连续块里。
内心OS:感觉没人会为了离散化而单独写一个树状数组吧...
摩尔投票法
用来求众数,时间复杂度 \(O(n)\) ,空间复杂度常数级。
分为两个操作:抵消和计数
抵消:两个投票不同时相互抵消
计数:两个投票相同时增加可被抵消的次数
Elaina's Code
int n,ans,cnt;
signed main(){
n=rd;
for(int i=1,x;i<=n;i++){
x=rd;
if(x!=ans){
--cnt;
}
if(cnt<=0){
++cnt;
ans=x;
}
}
printf("%lld",ans);
return Elaina;
}
Lambda表达式
基本语法如下
[capture list] (parameter list) -> return type { function body }
一个lambda表达式表示一个可调用的代码单元,就是一个函数
由于Lambda的类型是单一的,不能通过类型名来显式声明对应的对象,但可以利用auto关键字和类型推导
捕获列表可以捕获先前定义的变量并在函数主体中使用
举个栗子
int x=10,n;
auto f=[x](int a){return a>=x;};
cin>>n;
cout<<f(n);
//如果n>=10会输出1,否则输出0
lambda主要还是用于简化代码
再举个栗子
bool compare(int a,int b){//降序排序
return a>b;
}
sort(a, a+n, compare);
//等价于
sort(a, a+n, [](int a,int b){return a>b;});//降序排序
关于+=、-=、*=、=等运算符
她们是可以连着用的
比如
(ans+=cnt)%=p;
等价于
ans=(ans+cnt)%p;
m--和--m
很多人在类似\(n\)个数据\(m\)组问题的题目中 喜欢直接用 while(m--)
比如说我
但请记住是m--
不要写成--m
不然会导致少输入一组数据 调了一下午代码调出来的
例如以下代码
?
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;
n=m=5;
while(--m){
cout<<m<<' ';
}
cout<<'\n';
while(n--){
cout<<n<<' ';
}
return 0;
}
!
4 3 2 1
4 3 2 1 0
#ifdef ONLINE_JUDGE
#ifdef ONLINE_JUDGE
freopen("输入.in","r",stdin);
freopen("输出.out","w",stdout);
#endif
酱紫不用注释freopen就可以在本地调试
而且提交的时候就不会file error力qwq
PBDS
开了个大坑...以后来补
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
gp_hash_table<int ,int > mapp;
关于 #define int long long
OIwiki都在用\(#define int long long\)
我有什么理由不用呢
不过千万注意空间是否足够
关于数据流解绑
给输入输出流解绑,使其比肩scanf和printf的速度
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
注:
-
关闭了同步流,就不能用scanf和printf
否则如图
关闭后同时使用printf和cout
未关闭
你猜我为什么板子题还wa了两次 -
关闭了同步流,不能用getchar()函数
-
不能再用cout<<endl 而应该改用cout<<'\n'
通常情况下,cout<<endl会输出一个换行符并刷新输出缓冲区,造成一些时间耗费,确保内容立即显示。
但是,当使用了上述代码时,cout<<endl不再具有自动刷新缓冲区的功能。
所以即使不关闭同步流也推荐使用'\n'
关于浮点数相等的判断
因为浮点数的精度计算太过复杂
像3.14这样的数存在浮点型变量里存的可能是3.139999999,也有可能是3.140000001
所以不能直接用“==”判断两个浮点数是否相等。
在这种情况下,就允许判断两个浮点数为相等时,两数之间存在微小的误差
这个“微小的误差”要取一个较小的数
比如1e-8
这样就不会判不出也不会误判了
const double eps=1e-8;
bool eq(double x,double y){
//如果a和b之间相差的值小于eps(即1e-8),就说明它们是相等的
return fabs(x-y)<eps;//fabs用于取浮点数的绝对值
}
查错查了半天才发现打成了const int eps
关于三目运算符
a[i][j]=(i==j)
等价于
a[i][j]=i==j?1:0
关于神の逗号
如
return printf("%d",ans),0;
是合法的