码风优化

由于我代码风格极差(使用单字母或缩写或拼音命名,不空格,缩进只用空格不用tab,不写注释),因此导致了打代码时错误不断,难查找问题,导致比赛时出现大量无用时间,因此特此痛下决心改变码风。
参考:C++ 代码规范
测试用题:线段树
原代码

点击查看代码
#include<bits/stdc++.h>
#define for1(i,a,b) for(ll i=a;i<=b;i++)
#define ll long long
#define ls q*2
#define rs q*2+1
using namespace std;
struct node{
	ll l;
	ll r;
	ll lan;
	ll w;
}s[500005*4];
ll n,m,a[500005];
void build(ll q,ll l,ll r)
{
	s[q].l=l;
	s[q].r=r;
	s[q].lan=0;
	if(l==r)
	{
		s[q].w=a[l];
		return ;
	}
	ll mid=(l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	s[q].w=s[ls].w+s[rs].w;
}

void chuan(ll q)
{
	if(s[q].lan!=0)
	{
		s[ls].w+=s[q].lan*(s[ls].r-s[ls].l+1); 
		s[rs].w+=s[q].lan*(s[rs].r-s[rs].l+1); 
		s[ls].lan+=s[q].lan;
		s[rs].lan+=s[q].lan;
		s[q].lan=0;
	}
	return ;
}

void xg(ll q,ll l,ll r,ll k)
{
	if(s[q].l>=l&&s[q].r<=r)
	{
		s[q].w+=k*(s[q].r-s[q].l+1);
		s[q].lan+=k;
		return ; 
	}
	chuan(q);
	ll mid=(s[q].l+s[q].r)>>1;
	if(l<=mid) xg(ls,l,r,k);
	if(r>mid) xg(rs,l,r,k);
	s[q].w=s[ls].w+s[rs].w;
	return ;
}

ll cx(ll q,ll l,ll r)
{
//	cout<<q<<' '<<s[q].l<<' '<<s[q].r<<endl;
	if(s[q].l>=l&&s[q].r<=r)
	{
		return s[q].w; 
	}
	chuan(q);
	ll mid=(s[q].l+s[q].r)>>1;
	ll ans=0;
	if(l<=mid) ans+=cx(ls,l,r);
	if(r>mid) ans+=cx(rs,l,r);
	return ans;
}

int main()
{
	cin>>n>>m;
	for1(i,1,n) scanf("%d",a+i);
	ll x,y,k;
	build(1,1,n);
	for1(i,1,m)
	{
		ll ji;
		cin>>ji;
		if(ji==1)
		{
			cin>>x>>y>>k;
			xg(1,x,y,k);
		}
		else{
			cin>>x>>y;
			cout<<cx(1,x,y)<<endl;
		}
	}
	return 0;
}

调整后

点击查看代码
#include<bits/stdc++.h>
#define for1(i,a,b) for (ll i = a;i <= b;i ++)
#define ll long long
#define leftSon now*2
#define rightSon now*2+1
const ll N = 1e5;
ll a[N],n,m;

struct SegmentTree
{
	ll left[N * 4];
	ll right[N * 4];
	ll weight[N * 4];
	ll lazyTag[N * 4];

    SegmentTree()
    {
        for1(i,1,n*4)
            lazyTag[i] = 0;
    }

	void Build (const ll &now, const ll &l , const ll &r)//建树
	{
		left[now] = l;
		right[now] = r;

		if (l == r)
		{
			weight[now] = a[l];
			return ;
		}

		ll mid = (l + r) / 2;

		Build (leftSon, l, mid);
		Build (rightSon, mid+1, r);

		weight[now] = weight[leftSon] + weight[rightSon];
		return ;
	}

    void Lower (const ll &now)//下放懒标记
    {
        if(lazyTag[now] == 0) return ;

        weight[leftSon] += (right[leftSon] - left[leftSon] + 1) * lazyTag[now];
        weight[rightSon] += (right[rightSon] - left[rightSon] + 1) * lazyTag[now];

        lazyTag[leftSon] += lazyTag[now];
        lazyTag[rightSon] += lazyTag[now];

        lazyTag[now]=0;
        return ;
    }

    void Modify (const ll &now, const ll &l, const ll &r, const ll &k)
    {
        
        if (left[now] >= l && right[now] <= r)
        {
            weight[now] += (right[now] - left[now] + 1) * k;
            lazyTag[now] += k;
            return ;
        }

        Lower (now);

        ll mid = (left[now] + right[now]) / 2;

        if (l <= mid) Modify (leftSon, l, r, k);
        if (r > mid) Modify (rightSon, l, r, k);

		weight[now] = weight[leftSon] + weight[rightSon];
        return ;
    }
    ll Query (const ll &now, const ll &l, const ll &r)//回答询问
    {
        if (left[now] >= l && right[now] <= r)
            return weight[now];

        Lower (now);

        ll mid = (left[now] + right[now]) / 2;
        ll ans=0;

        if (l <= mid) ans += Query (leftSon, l, r);
        if (r > mid) ans += Query (rightSon, l, r);

        return ans;
    }
	
}Tree;

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	std::cin >> n >> m;
    for1(i,1,n)
        std::cin >> a[i];

    Tree.Build (1, 1, n);

    ll flag, x, y, k;
    
    for1(i,1,m)
    {
        std::cin >> flag;

        if (flag == 1)
        {
            std::cin >> x >> y >> k;
            Tree.Modify (1, x, y, k);
        }

        else
        {
            std::cin >> x >> y;
            std::cout<< Tree.Query (1, x, y) <<'\n';
        }
    }
	return 0;
}

测试用题:树状数组
原:

点击查看代码
#include<bits/stdc++.h>
#define for1(i,a,b) for (ll i = a;i <= b;i ++)
#define ll long long
#define leftSon now*2
#define rightSon now*2+1
const ll N = 5e5;
ll a[N],n,m;
struct BinaryIndexedTree
{
    int array[N*2];
    BinaryIndexedTree()
    {
        for1(i,1,n*2)
        array[i]=0;
    }

    int lowbit (const int &x)
    {
        return x&-x;
    }

    void Modify (const int &l, const int &k)
    {
    	int x=l;

        while (x <= n)
        {
            array[x] += k;
            x += lowbit(x);
        }

        return;
    }

    int Query (const int &l, const int &r)
    {
    	int x=l-1;
    	int y=r;
        int ans=0;

        while(y)
        {
            ans += array[y];
            y -= lowbit(y);
        }

        while(x)
        {
            ans -= array[x];
            x -= lowbit(x);
        }

        return ans;
    }
    
    void Build (const int &l, const int &r)
    {
        for1(i,l,r)
            Modify (i,a[i]);
    }
}Tree;
int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	std::cin >> n >> m;
    for1(i,1,n)
        std::cin >> a[i];

    Tree.Build (1, n);

    ll flag, x, y, k;
    
    for1(i,1,m)
    {
        std::cin >> flag;

        if (flag == 1)
        {
            std::cin >> x >> k;
            Tree.Modify (x, k);
        }

        else
        {
            std::cin >> x >> y;
            std::cout<< Tree.Query (x, y) <<'\n';
        }
    }
	return 0;
}

调整后

点击查看代码
#include<bits/stdc++.h>
#define for1(i,a,b) for (ll i = a;i <= b;i ++)
#define ll long long
#define leftSon now*2
#define rightSon now*2+1
const ll N = 5e5+10;
ll a[N],n,m;
struct BinaryIndexedTree
{
    int array[N];
    BinaryIndexedTree()
    {
        for1(i,1,n)
        array[i]=0;
    }

    int lowbit (const int &x)
    {
        return x&-x;
    }

    void Modify (const int &l, const int &k)
    {
    	int x=l;

        while (x <= n)
        {
            array[x] += k;
            x += lowbit(x);
        }

        return;
    }

    int Query (const int &l, const int &r)
    {
    	int x=l-1;
    	int y=r;
        int ans=0;

        while(y)
        {
            ans += array[y];
            y -= lowbit(y);
        }

        while(x)
        {
            ans -= array[x];
            x -= lowbit(x);
        }

        return ans;
    }
    
    void Build (const int &l, const int &r)
    {
        for1(i,l,r)
            Modify (i,a[i]);
    }
}Tree;
int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	std::cin >> n >> m;
    for1(i,1,n)
        std::cin >> a[i];

    Tree.Build (1, n);

    ll flag, x, y, k;
    
    for1(i,1,m)
    {
        std::cin >> flag;

        if (flag == 1)
        {
            std::cin >> x >> k;
            Tree.Modify (x, k);
        }

        else
        {
            std::cin >> x >> y;
            std::cout<< Tree.Query (x, y) <<'\n';
        }
    }
	return 0;
}

在根据新码风的方式打了之后能够明显感觉到的是:

  • 很不顺手,经常忘记加空格,std之类的
  • 打的时候用时较长
  • 可读行明显增强,看起来非常舒服
  • 常数明显变小,大概少了100~200ms左右
    等用了一段时间之后看看效果如何
    于2023/2/4更新

今天线段树合并写了250行,写的人都麻了,一进题解一看其他人同样的做法才80行。。。
感觉以后可以适当的不封装。。。

点击查看代码
#include<bits/stdc++.h>
#define for1(i,a,b) for (int i = a;i <= b;i ++)
#define ll long long
const int N = 1e6+10;
int n, m, Ans[N], R;
struct Side//边
{
    int nex;
    int to;

    Side()
    {
        int nex = 0;
        int to = 0;
    }
};
struct Segment//线段
{
    int l;
    int r;
    int t;//属于哪个点的线段树
    int d;//权值

    Segment()
    {
        l=r=t=d=0;
    }
};
struct Point//点
{
    int hd;
    int fa;//父亲
    int dep;//深度
    int rt;//该点的线段树的编号

    Point()
    {
        hd = 0;
        fa = 0;
        dep = 0;
    }
};


struct SegmentTree{
    Segment a[N*10];
    int cnt2;

    SegmentTree()
    {
        cnt2 = 0;
    }

    void PushUp (const int x)
    {
        if(a[a[x].l].d >= a[a[x].r].d) 
        {
            a[x].d = a[a[x].l].d;
            a[x].t = a[a[x].l].t;
        }
        else
        {
            a[x].d = a[a[x].r].d;
            a[x].t = a[a[x].r].t;
        }

        return ;
    }

    int Change (const int &ji, const int &x, const int &y, const int &pos, const int &val)
    //当前节点,左端点,右端点,修改的位置,修改的权值
    {
        int now = ji;
        if (ji == 0)
        now = ++ cnt2;//动态开点

        if (x == y)
        {
            a[now].d += val;
            a[now].t = x; 
            return now;
        }

        int mid = (x + y) / 2;
        if(pos <= mid) a[now].l = Change(a[now].l, x, mid, pos, val);
        else  a[now].r = Change(a[now].r, mid + 1, y, pos, val);
        PushUp(now);

        return now;
    }
    int Merge (int now1, int now2, int x, int y)//线段树合并
    {
        if (now1 == 0) return now2;
        if (now2 == 0) return now1;

        if (x == y)
        {
            a[now1].d += a[now2].d;
            a[now1].t = x;
            return now1;
        }

        int mid = (x + y) / 2;
        a[now1].l= Merge (a[now1].l, a[now2].l, x, mid);
        a[now1].r= Merge (a[now1].r, a[now2].r, mid + 1, y);
        PushUp (now1);

        return now1;
    }

}Tree;

struct  ChainTable//链表
{
    Point p[N];
    Side a[N * 2];
    int cnt1;
    int st[N][30];

    ChainTable()
    {
        cnt1 = 0;
    }

    void add (const int &x, const int &y)
    {
        a[++ cnt1].to = y;
        a[cnt1].nex = p[x].hd;
        p[x].hd = cnt1;
    }

    void dfs (const int &x,const int &fa)
    {

       	p[x].dep = p[fa].dep + 1;
       	p[x].fa = fa;
	    st[x][0] = fa;
	    for (int i=1;(1<<i) <= p[x].dep;i++)
	    	st[x][i] = st[st[x][i - 1]][i - 1];
     	for(int i=p[x].hd;i;i=a[i].nex)
	    {
	    	int v=a[i].to;
	    	if(v!=fa)
	    	dfs(v,x);
    	}
    }

    int Lca (int x, int y)
    {
        if (p[x].dep > p[y].dep)
            std::swap(x,y);
    	for (int i = 25;i >= 0;i--)
    	{
	    	if (p[y].dep - (1<<i) >= p[x].dep)
	    	y = st[y][i];
    	}

    	if(x==y)
	    	return x;
	    for(int i = 25;i >= 0;i --)
	    {
	    	if (st[x][i] != st[y][i])
	    	{
		    	x = st[x][i];
		    	y = st[y][i];
		    }
    	}
	return st[x][0];
    }

    void QianZhuiHe (const int &x)
    {
        for(int i = p[x].hd;i;i = a[i].nex)
        {
            int v = a[i].to;
            if(p[v].dep > p[x].dep)
            {
                QianZhuiHe(v);
                p[x].rt = Tree.Merge(p[x].rt, p[v].rt, 1, R);
            }
        }

        if(Tree.a[p[x].rt].d) 
            Ans[x] = Tree.a[p[x].rt].t;
    }
}lianBiao;
struct Query//询问
{
    int x;
    int y;
    int z;
    void Read(const int &l ,const int &r, const int &w)
    {
        x = l;
        y = r;
        z = w;
        return ;
    }
}xunWen[N];
int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
    std::cin >> n >> m;
    int x, y, z;
    for1(i,1,n-1)
    {
        std::cin >> x >> y;
        lianBiao.add(x,y);
        lianBiao.add(y,x);
    }
    lianBiao.p[1].dep=1;
    lianBiao.dfs (1, 0);

    for1(i,1,m)
    {
    	std::cin >> x >> y >> z;
        xunWen[i].Read(x,y,z);
        R = std::max(R,z);
    }

    for1(i,1,m)
    {
        int lca = lianBiao.Lca (xunWen[i].x, xunWen[i].y);
        int jx = xunWen[i].x, jy = xunWen[i].y,jz = xunWen[i].z;
        int jfa = lianBiao.p[lca].fa;

        lianBiao.p[jx].rt = Tree.Change (lianBiao.p[jx].rt, 1, R, jz, 1);
        lianBiao.p[jy].rt = Tree.Change (lianBiao.p[jy].rt, 1, R, jz, 1);

        lianBiao.p[lca].rt = Tree.Change (lianBiao.p[lca].rt, 1, R, jz, -1);

        if (jfa != 0)
            lianBiao.p[jfa].rt = Tree.Change (lianBiao.p[jfa].rt, 1, R, jz, -1);
    }
    lianBiao.QianZhuiHe(1);
    for1(i,1,n)
        std::cout<< Ans[i] << '\n';
    return 0;
	return 0;
}

2023/2/7更新
待续未完

posted @ 2023-02-04 10:48  yyx525jia  阅读(34)  评论(0)    收藏  举报