• 个人简介

    我练习打字两年半,至今仍是一指禅。

    我练习打字两年半,至今仍是一指禅。

    我练习打字两年半,至今仍是一指禅。

    我练习打字两年半,至今仍是一指禅。

    我练习打字两年半,至今仍是一指禅。
    我练习打字两年半,至今仍是一指禅。

    一些模板

    #include<bits/stdc++.h>
    #define int long long
    #define inf 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const int N=100010;
    int n,m;
    int idx;
    struct node
    {
    	int fath,dep,dfn,siz;
    	int top,son;
    	vector<int>G;
    }point[N];
    void dfs1(int u,int fa)
    {
    	point[u].fath=fa; point[u].dep=point[fa].dep+1; point[u].siz=1;
    	for(int v : point[u].G)
    	{
    		if(v==fa) continue;
    		dfs1(v,u);
    		point[u].siz+=point[v].siz;
    		if(point[v].siz>point[point[u].son].siz) point[u].son=v;
    	}
    }
    void dfs2(int u,int fatop)
    {
    	point[u].top=fatop; point[u].dfn=++idx;
    	if(point[u].son) dfs2(point[u].son,fatop);
    	for(int v:point[u].G) if(v!=point[u].son && v!=point[u].fath) 
    		dfs2(v,v);
    }
    int a[N],val[N];
    struct nodex
    {
    	int l,r,data,sum,lazy;
    }t[N<<2];
    void build(int p,int l,int r)
    {
    	t[p].l=l,t[p].r=r;
    	t[p].lazy=0;
    	if(l==r)
    	{
    		t[p].data=val[l];
    		t[p].sum=val[l];
    		return;
    	}
    	int mid=l+r>>1;
    	build(p<<1,l,mid);
    	build(p<<1|1,mid+1,r);
    	t[p].data=max(t[p<<1].data,t[p<<1|1].data);
    	t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
    }
    void pushdown(int p)
    {
    	if(t[p].lazy)
    	{
    		t[p<<1].sum=t[p<<1].sum+t[p].lazy*(t[p<<1].r-t[p<<1].l+1);
    		t[p<<1].data=t[p<<1].data+t[p].lazy;
    		t[p<<1].lazy=t[p<<1].lazy+t[p].lazy;
    		t[p<<1|1].sum=t[p<<1|1].sum+t[p].lazy*(t[p<<1|1].r-t[p<<1|1].l+1);
    		t[p<<1|1].data=t[p<<1|1].data+t[p].lazy;
    		t[p<<1|1].lazy=t[p<<1|1].lazy+t[p].lazy;
    		t[p].lazy=0;
    	}
    }
    void add1(int p,int x,int k)//单点修改
    {
    	if(t[p].l==t[p].r)
    	{
    		t[p].data+=k;
    		t[p].sum+=k;
    		return;
    	}
    	pushdown(p);
    	int mid=t[p].l+t[p].r>>1;
    	if(x<=mid) add1(p<<1,x,k);
    	if(x>mid) add1(p<<1|1,x,k);
    	t[p].data=max(t[p<<1].data,t[p<<1|1].data);
    	t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
    }
    void add2(int p,int l,int r,int k)//区间修改
    {
    	if(l<=t[p].l && t[p].r<=r)
    	{
    		t[p].sum=t[p].sum+k*(t[p].r-t[p].l+1);
    		t[p].data=t[p].data+k;
    		t[p].lazy=t[p].lazy+k;
    		return;
    	}
    	pushdown(p);
    	int mid=t[p].l+t[p].r>>1;
    	if(l<=mid) add2(p<<1,l,r,k);
    	if(r>mid) add2(p<<1|1,l,r,k);
    	t[p].data=max(t[p<<1].data,t[p<<1|1].data);
    	t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
    }
    int querymax(int p,int l,int r)//区间查询最大值
    {
    	if(l<=t[p].l&&t[p].r<=r) return t[p].data;
    	pushdown(p);
    	int mid=t[p].l+t[p].r>>1;
    	int ret=-inf;
    	if(l<=mid) ret=max(ret,querymax(p<<1,l,r));
    	if(r>mid) ret=max(ret,querymax(p<<1|1,l,r));
    	return ret;
    }
    int querysum(int p,int l,int r)//区间求和查询
    {
    	if(l<=t[p].l && t[p].r<=r) return t[p].sum;
    	pushdown(p);
    	int mid=t[p].l+t[p].r>>1;
    	int ret=0;
    	if(l<=mid) ret+=querysum(p<<1,l,r);
    	if(r>mid) ret+=querysum(p<<1|1,l,r);
    	return ret;
    }
    signed main()
    {
    	ios::sync_with_stdio(0);
    	cin.tie(0); cout.tie(0);
    	cin>>n>>m;
    	for(int i=1;i<=n;i++) cin>>a[i];
    	for(int i=1;i<n;i++)
    	{
    		int u,v; cin>>u>>v;
    		point[u].G.push_back(v);
    		point[v].G.push_back(u);	
    	}
    	dfs1(1,0); dfs2(1,1);
    	for(int i=1;i<=n;i++) val[point[i].dfn]=a[i];
    	build(1,1,n);
    	while(m--)
    	{
    		int op; cin>>op;
    		if(op==1)//单点修改
    		{
    			int u,t; cin>>u>>t;
    			add1(1,point[u].dfn,t);
    			a[u]+=t;
    		}
    		if(op==2)//子树修改
    		{
    			int u,t; cin>>u>>t;
    			add2(1,point[u].dfn,point[u].dfn+point[u].siz-1,t);
    		}
    		if(op==3)//路径修改
    		{
    			int u,v,t; cin>>u>>v>>t;
    			while(point[u].top!=point[v].top)
    			{
    				if(point[point[u].top].dep>point[point[v].top].dep) 
    					swap(u,v);
    				add2(1,point[point[v].top].dfn,point[v].dfn,t);
    				v=point[point[v].top].fath;
    			}
    			if(point[u].dep>point[v].dep) swap(u,v);
    			add2(1,point[u].dfn,point[v].dfn,t);
    		}
    		if(op==4)//路径最大值查询 
    		{
    			int u,v; cin>>u>>v;
    			int ans=-inf;
    			while(point[u].top!=point[v].top)
    			{
    				if(point[point[u].top].dep>point[point[v].top].dep) 
    					swap(u,v);
    				ans=max(ans,querymax(1,point[point[v].top].dfn,point[v].dfn));
    				v=point[point[v].top].fath;
    			}
    			if(point[u].dep>point[v].dep) swap(u,v);
    			ans=max(ans,querymax(1,point[u].dfn,point[v].dfn));
    			cout<<ans<<"\n";
    		}
    		if(op==5)//路径和查询 
    		{
    			int u,v; cin>>u>>v;
    			int ans=0;
    			while(point[u].top!=point[v].top)
    			{
    				if(point[point[u].top].dep>point[point[v].top].dep) 
    					swap(u,v);
    				ans+=querysum(1,point[point[v].top].dfn,point[v].dfn);
    				v=point[point[v].top].fath;
    			}
    			if(point[u].dep>point[v].dep) swap(u,v);
    			ans+=querysum(1,point[u].dfn,point[v].dfn);
    			cout<<ans<<"\n";
    		}
    		if(op==6)//子树最大值查询
    		{
    			int u; cin>>u;
    			int ans=querymax(1,point[u].dfn,point[u].dfn+point[u].siz-1);
    			cout<<ans<<"\n";
    		}
    		if(op==7)//子树和查询
    		{
    			int u; cin>>u;
    			int ans=querysum(1,point[u].dfn,point[u].dfn+point[u].siz-1);
    			cout<<ans<<"\n";
    		}
    	}
    	return 0; 
    }
    
    #include <bits/stdc++.h>
    #define int long long
    #define inf 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const int N=1e5+5;
    int a[N],n,m;
    struct node
    {
    	int l,r,data,sum,lazy;
    }t[N<<2];
    //建树 
    void build(int p,int l,int r)
    {
    	t[p].l=l,t[p].r=r;
    	t[p].lazy=0;
    	if(l==r)
    	{
    		t[p].data=a[l];
    		t[p].sum=a[l];
    		return;
    	}
    	int mid=l+r>>1;
    	build(p<<1,l,mid);
    	build(p<<1|1,mid+1,r);
    	t[p].data=max(t[p<<1].data,t[p<<1|1].data);
    	t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
    }
    // 传懒标记
    void pushdown(int p)
    {
    	if(t[p].lazy)
    	{
    		//更新左子树
    		t[p<<1].sum+=t[p].lazy*(t[p<<1].r-t[p<<1].l+1);
    		t[p<<1].data+=t[p].lazy;
    		t[p<<1].lazy+=t[p].lazy;
    		//更新右子树
    		t[p<<1|1].sum+=t[p].lazy*(t[p<<1|1].r-t[p<<1|1].l+1);
    		t[p<<1|1].data+=t[p].lazy;
    		t[p<<1|1].lazy+=t[p].lazy;
    		t[p].lazy=0;
    	}
    }
    // 单点修改
    void add1(int p,int x,int k)
    {
    	if(t[p].l==t[p].r)
    	{
    		t[p].data+=k;
    		t[p].sum+=k;
    		return;
    	}
    	pushdown(p);
    	int mid=t[p].l+t[p].r>>1;
    	if(x<=mid) add1(p<<1,x,k);
    	else add1(p<<1|1,x,k);
    	t[p].data=max(t[p<<1].data,t[p<<1|1].data);
    	t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
    }
    //区间查询最大值
    int query1(int p,int l,int r)
    {
    	if(l<=t[p].l&&t[p].r<=r) return t[p].data;
    	pushdown(p);
    	int mid=t[p].l+t[p].r>>1;
    	int ret=-inf;
    	if(l<=mid) ret=max(ret,query1(p<<1,l,r));
    	if(r>mid) ret=max(ret,query1(p<<1|1,l,r));
    	return ret;
    }
    //区间修改
    void add2(int p,int l,int r,int k)
    {
    	if(l<=t[p].l&&t[p].r<=r)
    	{
    		t[p].sum+=k*(t[p].r-t[p].l+1);
    		t[p].data+=k;
    		t[p].lazy+=k;
    		return;
    	}
    	pushdown(p);
    	int mid=t[p].l+t[p].r>>1;
    	if(l<=mid) add2(p<<1,l,r,k);
    	if(r>mid) add2(p<<1|1,l,r,k);
    	t[p].data=max(t[p<<1].data,t[p<<1|1].data);
    	t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
    }
    //区间求和查询
    int query2(int p,int l,int r)
    {
    	if(l<=t[p].l&&t[p].r<=r) return t[p].sum;
    	pushdown(p);
    	int mid=t[p].l+t[p].r>>1;
    	int ret=0;
    	if(l<=mid) ret+=query2(p<<1,l,r);
    	if(r>mid) ret+=query2(p<<1|1,l,r);
    	return ret;
    }
    signed main()
    {
    	ios::sync_with_stdio(0);
    	cin.tie(0); cout.tie(0);
    	cin>>n>>m;
    	for(int i=1;i<=n;i++) cin>>a[i];
    	build(1,1,n);
    	for(int i=1;i<=m;i++)
    	{
    		int op;
    		cin>>op;
    		if(op==1)//单点修改
    		{
    			int x,k;
    			cin>>x>>k;
    			add1(1,x,k);
    		}
    		else if(op==2)//区间查询最大值
    		{
    			int l,r;
    			cin>>l>>r;
    			cout<<query1(1,l,r)<<"\n";
    		}
    		else if(op==3)//区间修改
    		{
    			int l,r,k;
    			cin>>l>>r>>k;
    			add2(1,l,r,k);
    		}
    		else if(op==4)//区间求和查询
    		{
    			int l,r;
    			cin>>l>>r;
    			cout<<query2(1,l,r)<<"\n";
    		}
    	}
    	return 0;
    }
    

    惊喜

  • 通过的题目

  • 最近活动

题目标签

教程
19
stl
7
高精度
5
搜索
5
枚举
5
其他
5
CSP-J
4
模拟
3
NOIP
3
语法
3
动态规划
3
贪心
3
构造
3
2015
2
2020
2
NOIP 普及组
2
NOIP 提高组
2
A
2
1
1
2002
1