算法记录

  • 1<<n //相当于2^n

离散化

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)
*/


posted @ 2020-06-25 22:52  特立独行的猪猪  阅读(111)  评论(0编辑  收藏  举报