数据类型 | 二进制表示范围 | 十进制表示范围 |
---|---|---|
int (4字节) | -2^31 ~ 2^31-1 | -2147483648 ~ 2147483647 |
long long(8字节) | -2^63 ~ 2^63-1 | 9223372036854775807~-9223372036854775808 |
快速幂的函数
// 快速幂 a^n % P
int qmi(long long a,int n,int mod){
int res=1;
while(n){
if(n&1){
res=res*a%mod;//mod是题目给的取的模的值
n=n>>1;//n>>=1;
a=(a*a)%mod;
}
}
return res;
}
快速排序
void quik_sort(int q[],int l,int r){
while(l>=r) return;
int i=l-1,j=r+1,x=q[l+r>>1];
while(i<j){ //注意这边的括号里是i,j
do i++; while(q[i]<x);
do j--; while(q[j]>x);
if(i<j) swap(q[i],q[j]);
}
quik_sort(q,l,j);
quik_sort(q,j+1,r);
}
差分矩阵计算的方法
//插入(x1,y1)到(x2,y2)数值c
void insert(int x1,int y1,int x2,int y2,int c){
s[x1][y1] +=c;
s[x2+1][y1] -=c;
s[x1][y2+1] -=c;
s[x2+1][y2+1] +=c;
}
//用insert函数初始化差分矩阵的方法
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
insert(i,j,i,j,a[i][j]);
}
}
//恢复原来的矩阵
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
//求s的前缀和
s[i][j]=s[i][j]+ s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];
}
}
队列的用法
typedef pair<int ,int> PII;
vector<int> alls; //单个数字的队列
vector<PII> add,query; //一对数组为元素的队列
//添加元素的方法
alls.push_back(x);
add.push_back({x,c});
//排序的方法
sort(alls.begin(),alls.end());
alls.erase(unique(alls.begin(),alls.end()),alls.end());
//unique()这个函数的作用就是将这个数组中的所有重复元素移动到最后
//并返回数组中不重复元素的尾端点
//erase()函数的作用是去掉这些重复的元素
//输出结果
for(auto item:query){
int l = find(item.first), r = find(item.second);
printf("%d\n",s[r]-s[l-1]);
}
字符串的处理
//C++的字符串结尾是0
//因此可以用如下的方法作为字符串str循环结束的判断条件
for(int i=0;str[i];i++){
}
线段树
//关于线段树的四个核心函数
//1.pushup:用子节点信息更新当前节点信息(仅有一句,有时会被省略)
//2.build:在一段区间上初始化线段树
//3.modify:修改操作
//4.query:查询操作
//5.pushdown:带懒标记的操作(懒标记用来更改维护的线段树的区间)
#include <bits/stdc++.h>
using namespace std;
const int N=100010;
int n,m;
int w[N];
struct Node{
int l,r;
int sum;
}tr[N*4];
void pushup(int u){
tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}
void build(int u,int l,int r){
if(l==r) tr[u]={l,r,w[r]};
else{
tr[u]={l, r};
int mid=(l+r)>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
pushup(u);
}
}
int query(int u,int l,int r){
if(tr[u].l>=l && tr[u].r<=r) return tr[u].sum;
int mid=(tr[u].l+tr[u].r)>>1;
int sum=0;
if(l<=mid) sum=query(u<<1,l,r);
if(r>mid) sum+=query(u<<1|1,l,r);
return sum;
}
void modify(int u,int x,int v){
if(tr[u].l==tr[u].r) tr[u].sum+=v;
else{
int mid=(tr[u].l+tr[u].r)>>1;
if(x<=mid) modify(u<<1,x,v);
else modify(u << 1 | 1, x, v);
pushup(u);
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) scanf("%d",&w[i]);
build(1,1,n);
int k,a,b;
while(m--){
scanf("%d%d%d",&k,&a,&b);
//k=0,表示求子数列[a,b]的和;
//k=1,表示第a个数加b
if(k==0) printf("%d\n",query(1,a,b));
else modify(1,a,b);
//关于参数(1,a,b)
//其中的1是根节点编号
}
return 0;
}