离散化
int a[N];
vector<int>tmp;
for(int i=0;i<N;i++) tmp.push_back(a[i]);
sort(tmp.begin(),tmp.end());
tmp.erase(unique(tmp.begin(),tmp.end()),tmp.end());
for(int i=0;i<N;i++)
{
a[i] = lower_bound(tmp.begin(),tmp.end(),a[i])-tmp.begin();
}
// a[i]为离散化的数组
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int tree[500010],rank[500010],n;
long long ans;
struct point
{
int num,val;
}a[500010];
inline bool cmp(point q,point w)
{
if(q.val==w.val)
return q.num<w.num;
return q.val<w.val;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i].val),a[i].num=i;
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++)
{
rank[a[i].num]=i;
}
for(int i=1;i<=n;i++)
{
cout<<rank[i]<<" ";
}
return 0;
}
/*
5
104 102 101 105 103
4 2 1 5 3
*/
树状数组
void add(int p, int x){ //给位置p增加x
while(p <= n) sum[p] += x, p += p & -p;
}
int ask(int p){ //求位置p的前缀和
int res = 0;
while(p) res += sum[p], p -= p & -p;
return res;
}
int range_ask(int l, int r){ //区间求和
return ask(r) - ask(l - 1);
}
线段树
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+5;
struct tree{
int l,r;
ll val,add;
}t[maxn*4];
ll a[maxn];
// 建树
void build(int p,int l,int r)
{ // 以p为编号的节点维护的区间为l到r
t[p].l=l;t[p].r=r;
if(l==r)
{
t[p].val=a[l];
return;
}
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
t[p].val=t[p<<1].val+t[p<<1|1].val;
}
void spread(int p)
{ // 如果懒标记不为0,就将其下传,修改左右儿子维护的值
if(t[p].add)
{
// 修改val:在区间查询要用到
t[p<<1].val += t[p].add*(t[p<<1].r-t[p<<1].l+1);
t[p<<1|1].val += t[p].add*(t[p<<1|1].r-t[p<<1|1].l+1);
t[p<<1].add += t[p].add;
t[p<<1|1].add += t[p].add;
t[p].add=0; // 下传之后将该节点的懒标记清0
}
}
// 区间修改
void change(int p,int x,int y,ll z)
{ //修改的区间覆盖了当前节点时,我们就把这个区间给修改,并打上懒标记
if(x<=t[p].l && y>=t[p].r)
{
t[p].val += z*(t[p].r-t[p].l+1);
t[p].add += z;
return ;
}
spread(p); // 到这里是没有覆盖的,所以要标记下放
int mid=(t[p].l+t[p].r)>>1;
if(x<=mid) change(p<<1,x,y,z);//如果要修改的区间覆盖了左儿子,就修改左儿子
if(y>=mid+1) change(p<<1|1,x,y,z);
t[p].val = t[p<<1].val + t[p<<1|1].val;
}
//区间查询
ll ask(int p,int x,int y)
{
if(x<=t[p].l && y>=t[p].r) return t[p].val; //恰好覆盖
spread(p);
int mid=(t[p].l+t[p].r)>>1;
ll ans=0;
if(x<=mid) ans += ask(p<<1,x,y);
if(y>=mid+1) ans += ask(p<<1|1,x,y);
return ans;
}
void show()
{
for(int p=1;t[p].val>0;p++)
{
printf("(%d %d) val=%d add=%d\n",t[p].l,t[p].r,t[p].val,
t[p].add);
}
puts("");
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
while(m--)
{
ll q,x,y,k;
cin>>q>>x>>y;
if(q==1)
{
cin>>k;
change(1,x,y,k);
}
else
{
cout<<ask(1,x,y)<<endl;
}
}
}
质因数分解
for(int i=2;i*i<=p;i++){ //对质因数进行分解
if(p%i==0){
primer[++k]=i; //注意这里是++k
while(p%i==0){
num[k]++;
p/=i;
}
}
}
if(p>1) primer[++k]=p,num[k]++;
dfs序
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+5;
int n,m;
vector<int>g[maxn];
int in[maxn],out[maxn];
int times;
void dfs(int u,int fa)
{
in[u] = ++times;
for(int i=0;i<g[u].size();i++)
{
int v = g[u][i];
if(v == fa) continue;// 无向图,可能回到父节点
dfs(v,u);
}
out[u] = times;
}
int main()
{
cin>>n;
for(int i=1;i<=n-1;i++)
{
int u,v;cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
// 构建dfs序列
times=0;
dfs(1,0);
for(int i=1;i<=n;i++)
{
printf("%d (in=%d out=%d)\n",i,in[i],out[i]);
}
}
/*
7
1 2
1 3
1 4
2 5
2 6
4 7
dfs序:
1 (in=1 out=7)
2 (in=2 out=4)
3 (in=5 out=5)
4 (in=6 out=7)
5 (in=3 out=3)
6 (in=4 out=4)
7 (in=7 out=7)
*/