zoukankan      html  css  js  c++  java
  • [BZOJ5028]小Z的加油店

    [BZOJ5028]小Z的加油店

    题目大意:

    一个长度为(n(nle10^5))的数列,(m(mle10^5))次操作,支持区间加和区间(gcd)

    思路:

    线段树维护差分,(gcd(A_l,cdots,A_r))就是区间([l,r])差分的(gcd)(A_r)(gcd)

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    const int N=1e5+1;
    int a[N];
    class SegmentTree {
    	#define _left <<1
    	#define _right <<1|1
    	#define mid ((b+e)>>1)
    	private:
    		int gcd[N<<2],sum[N<<2];
    		void push_up(const int &p) {
    			gcd[p]=std::__gcd(gcd[p _left],gcd[p _right]);
    			sum[p]=sum[p _left]+sum[p _right];
    		}
    	public:
    		void build(const int &p,const int &b,const int &e) {
    			if(b==e) {
    				gcd[p]=sum[p]=a[b];
    				return;
    			}
    			build(p _left,b,mid);
    			build(p _right,mid+1,e);
    			push_up(p);
    		}
    		void modify(const int &p,const int &b,const int &e,const int &x,const int &y) {
    			if(b==e) {
    				gcd[p]+=y;
    				sum[p]+=y;
    				return;
    			}
    			if(x<=mid) modify(p _left,b,mid,x,y);
    			if(x>mid) modify(p _right,mid+1,e,x,y);
    			push_up(p);
    		}
    		int query_gcd(const int &p,const int &b,const int &e,const int &l,const int &r) const {
    			if(b==l&&e==r) return gcd[p];
    			if(r<=mid) return query_gcd(p _left,b,mid,l,r);
    			if(l>mid) return query_gcd(p _right,mid+1,e,l,r);
    			return std::__gcd(query_gcd(p _left,b,mid,l,mid),query_gcd(p _right,mid+1,e,mid+1,r));
    		}
    		int query_sum(const int &p,const int &b,const int &e,const int &x) const {
    			if(e==x) return sum[p];
    			if(x<=mid) return query_sum(p _left,b,mid,x);
    			if(x>mid) return sum[p _left]+query_sum(p _right,mid+1,e,x);
    		}
    	#undef _left
    	#undef _right
    	#undef mid
    };
    SegmentTree t;
    int main() {
    	const int n=getint(),m=getint();
    	for(register int i=1;i<=n;i++) a[i]=getint();
    	for(register int i=n;i>=1;i--) a[i]-=a[i-1];
    	t.build(1,1,n);
    	for(register int i=0;i<m;i++) {
    		const int opt=getint(),l=getint(),r=getint();
    		if(opt==1) {
    			if(l<r) {
    				printf("%d
    ",std::abs(std::__gcd(t.query_sum(1,1,n,r),t.query_gcd(1,1,n,l+1,r))));
    			} else {
    				printf("%d
    ",t.query_sum(1,1,n,r));
    			}
    		} else {
    			const int v=getint();
    			t.modify(1,1,n,l,v);
    			if(r<n) t.modify(1,1,n,r+1,-v);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    CStdioFile的Writestring无法写入中文的问题
    Warning: skipping non-radio button in group. 的处理
    Linux命令 改变文档权限及所有者
    动态链接库dll的 静态加载 与 动态加载
    switch的方便用法
    mysql 安装过程中的错误:my-template.ini could not be processed and written to XXXmy.ini.Error code-1
    HDU 3790 最短路径问题 (SPFA)
    container_of用法及实现
    ZXing工具类v1.0
    基于MapReduce的HBase开发
  • 原文地址:https://www.cnblogs.com/skylee03/p/9346311.html
Copyright © 2011-2022 走看看