zoukankan      html  css  js  c++  java
  • 线段树(Onlogn)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef struct{
    	ll l,r,w,f;
    }Node;
    Node nodes[1000000]={0,0,0};
    ll x,y,ans,mod,single;
    void lazyFlag(ll k);
    void build(ll l,ll r,ll n)
    {//建树
    	nodes[n].l=l;nodes[n].r=r;
    	if(nodes[n].l==nodes[n].r)
    	{
    		scanf("%lld",&nodes[n].w);
    		return;
    	}
    	build(l,(l+r)/2,n*2);
    	build((l+r)/2+1,r,n*2+1);
    	nodes[n].w=nodes[n*2+1].w+nodes[n*2].w;
    }
    void singleSearch(ll k)
    {//单点查询
    	if(nodes[k].l==nodes[k].r)
    	{
    		printf("%lld",nodes[k].w);
    		return;
    	}
    	if(nodes[k].f) lazyFlag(k);
    	ll mid=(nodes[k].l+nodes[k].r)/2;
    	if(single<=mid)singleSearch(k*2);
    	else singleSearch(k*2+1);
    }
    void singleChange(ll k)
    {//单点修改
    	if(nodes[k].l==nodes[k].r)
    	{
    		nodes[k].w+=mod;
    		return;
    	}
    	if(nodes[k].f) lazyFlag(k);
    	ll mid=(nodes[k].l+nodes[k].r)/2;
    	if(single<=mid)singleChange(2*k);
    	else singleChange(2*k+1);
    	//nodes[k].w+=mod;
    	nodes[k].w=nodes[2*k].w+nodes[2*k+1].w;//更改区间状态
    }
    void partSearch(ll k)
    {//区间查询
    	if(nodes[k].l>=x&&nodes[k].r<=y)
    	{
    		ans+=nodes[k].w;
    		return;
    	}
    	if(nodes[k].f) lazyFlag(k);
    	ll mid=(nodes[k].l+nodes[k].r)/2;
    	if(x<=mid)partSearch(k*2);//左
    	if(y>mid)partSearch(k*2+1);//右
    }
    void partChange(ll k)
    {//懒标记(表示区间下面的子节点等待+mod)
    	
    	if(nodes[k].l>=x&&nodes[k].r<=y)
    	{
    		nodes[k].w+=(nodes[k].r-nodes[k].l+1)*mod;
    		nodes[k].f+=mod;
    		return;
    	}
    	if(nodes[k].f) lazyFlag(k);//懒标记下传
    	ll mid=(nodes[k].l+nodes[k].r)/2;
    	if(x<=mid)partChange(k*2);
    	if(y>mid)partChange(k*2+1);
    	nodes[k].w=nodes[2*k].w+nodes[2*k+1].w;//更新区间状态
    }
    void lazyFlag(ll k)
    {
    	nodes[k*2].f+=nodes[k].f;
    	nodes[k*2+1].f+=nodes[k].f;
    	nodes[k*2].w+=nodes[k].f*(nodes[k*2].r-nodes[k*2].l+1);
    	nodes[k*2+1].w+=nodes[k].f*(nodes[k*2+1].r-nodes[k*2+1].l+1);
    	nodes[k].f=0;
    }
    int main()
    {
    	//freopen("out.out","w",stdout);
    	ll m,n;cin>>n>>m;
    	build(1,n,1);
    	//prll(n);
    	for(ll i=0;i<m;i++)
    	{
    		ll op;cin>>op;
    		if(op==1)
    		{
    			cin>>x>>y>>mod;
    			partChange(1);
    			//print(n);
    		}
    		if(op==2)
    		{
    			cin>>x>>y;
    			partSearch(1);
    			cout<<ans<<endl;
    			ans=0;
    		}
    	}
    	return 0;
    }
    
    作者:xmsi
    出处:http://www.cnblogs.com/tldr/
    本文版权归作者和博客园共有,欢迎转载,但转载时请保留此段声明。
  • 相关阅读:
    Intel 10nm全系曝光!巨头也跑不动了
    国产智能手机占据半壁江山却依旧难掩三大尴尬事实
    顺势而为,HTML发展与UI组件设计进化
    怎么让引导不再是无用小透明?
    C++BUILDER的文件操作
    C++ Builder获取系统文件的路径
    C++Builder 常用String
    C++ 判断是否为邮箱格式
    AnsiString, String, char,char
    BCB如何编写,调用动态链接库DLL
  • 原文地址:https://www.cnblogs.com/tldr/p/10877953.html
Copyright © 2011-2022 走看看