• 算法记录


    • 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
    ",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)
    ",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)
    */
    
    
    
  • 相关阅读:
    php中的抽象方法和抽象类,简单明了,一点通
    PHP_保留两位小数并且四舍五入(可用于精度计算)_保留两位小数并且不四舍五入
    如何使用php生成唯一ID的4种方法
    Redis案例——商品秒杀,购物车
    centos+python2+apache2+django环境搭建
    前端上传图片并显示
    通过容器提交镜像(docker commit)以及推送镜像(docker push)
    Name or service not known原因大全
    VMware Workstation 与 Device/Credential Guard 不兼容.在禁用 Device/Credenti
    win10家庭版VMware,禁用Device/Credential Guard不兼容问题
  • 原文地址:https://www.cnblogs.com/xiaoxiao179/p/13193305.html
Copyright © 2020-2023  润新知