zoukankan      html  css  js  c++  java
  • [JSOI2009]等差数列

    洛谷水过了,bzoj超时了

    插入等差数列=》绝对是差分

    至于能分成几个等差数列,浓浓的dp阴谋味;
    好吧,正常的线段树收标记

    维护

    因为是差分=>且不用管数值
    要跳过非连续等差数列首项

    当前区间如果左右端点都不选有多少个等差数列 -> s[0]

    当前区间如果只选左端点有多少个等差数列 -> s[1]

    当前区间如果只选右端点有多少个等差数列 -> s[2]

    当前区间如果左右端点都选有多少个等差数列 -> s[3]

    #include<bits/stdc++.h>
    #define re return
    #define ll long long
    #define lson rt<<1
    #define rson rt<<1|1 
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    #define dec(i,l,r) for(int i=l;i>=r;--i)
    const int maxn=10e5+5;
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
    	char c;bool f=0;
    	while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
    	x=c^48;
    	while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
    	if(f)x=-x;
    }
    
    int n,m,cnt,b[maxn];
    
    struct data
    {
    	int l,r,s[4];	
    	inline data operator+(data rs)const
    	{
    		data ans;
    		ans.l=l;ans.r=rs.r;
    		ans.s[0]=s[2]+rs.s[1]-(rs.l==r);
    		ans.s[0]=min(ans.s[0],s[2]+rs.s[0]);ans.s[0]=min(ans.s[0],s[0]+rs.s[1]);
    		ans.s[1]=s[3]+rs.s[1]-(rs.l==r);
    		ans.s[1]=min(ans.s[1],s[1]+rs.s[1]);ans.s[1]=min(ans.s[1],s[3]+rs.s[0]);
    		ans.s[2]=s[2]+rs.s[3]-(rs.l==r);
    		ans.s[2]=min(ans.s[2],s[2]+rs.s[2]);ans.s[2]=min(ans.s[2],s[0]+rs.s[3]);
    		ans.s[3]=s[3]+rs.s[3]-(rs.l==r);
    		ans.s[3]=min(ans.s[3],s[1]+rs.s[3]);ans.s[3]=min(ans.s[3],s[3]+rs.s[2]);
    		re ans;
    	} 
    };
    struct node{
    	int val;data x;
    }tree[maxn<<2];
    inline void build(int rt,int l,int r)
    {
    	if(l==r)
    	{
    		tree[rt].x.s[1]=tree[rt].x.s[2]=tree[rt].x.s[3]=1;
    		tree[rt].x.l=tree[rt].x.r=b[l+1]-b[l];
    		tree[rt].val=tree[rt].x.s[0]=0;
    		re ;
    	}
    	tree[rt].val=0;
    	int mid=(l+r)>>1;
    	build(lson,l,mid);
    	build(rson,mid+1,r); 
    	tree[rt].x=tree[lson].x+tree[rson].x;
    }
    
    inline void pushdown(int rt)
    {
    	tree[lson].val+=tree[rt].val;tree[rson].val+=tree[rt].val;
    	tree[lson].x.l+=tree[rt].val;tree[rson].x.l+=tree[rt].val;
    	tree[lson].x.r+=tree[rt].val;tree[rson].x.r+=tree[rt].val;
    	tree[rt].val=0;
    	re;
    }
    
    inline void add(int rt,int l,int r,int x,int y,int num)
    {
    	if(x<=l&&r<=y)
    	{
    		tree[rt].val+=num;
    		tree[rt].x.l+=num;
    		tree[rt].x.r+=num;
    		re ;
    	}
    	if(tree[rt].val)pushdown(rt);
    	int mid=(l+r)>>1;
    	if(x<=mid)add(lson,l,mid,x,y,num);
    	if(y>mid)add(rson,mid+1,r,x,y,num);
    	tree[rt].x=tree[lson].x+tree[rson].x;
    }
    
    inline data query(int rt,int l,int r,int x,int y)
    {
    	if(x<=l&&r<=y)re tree[rt].x;
    	if(tree[rt].val)pushdown(rt);
    	int mid=(l+r)>>1;
    	data v;
    	if(y<=mid)v=query(lson,l,mid,x,y);
    	else if(mid<x)v=query(rson,mid+1,r,x,y);
    	else v=query(lson,l,mid,x,y)+query(rson,mid+1,r,x,y);
    	tree[rt].x=tree[lson].x+tree[rson].x;
    	re v;
    	
    }
    int main()
    {
    //	freopen("in.txt","r",stdin);
    	rd(n);
    	inc(i,1,n)
    	rd(b[i]);
    	build(1,1,n-1);
    	char c;
    	int q,s,t,a,b;
    	rd(q);
    	inc(i,1,q)
    	{
    		while((c=getchar())!='A'&&c!='B');
    		if(c=='A')
    		{
    			rd(s),rd(t),rd(a),rd(b);
    			if(s!=1)add(1,1,n-1,s-1,s-1,a);
    			if(t!=n)add(1,1,n-1,t,t,-(a+b*(t-s)));
    			if(s!=t)add(1,1,n-1,s,t-1,b);
    		}
    		else {
    			rd(s),rd(t);
    			if(s==t)
    			{
    				printf("1
    ");
    				continue;
    			}
    			else
    			{
    				data v=query(1,1,n-1,s,t-1);
    				printf("%d
    ",v.s[3]);
    			}
    		}
    	}
    	re 0;
    }
    
  • 相关阅读:
    MySQL-事务相关知识
    Linux脚本-自动ping网址列表
    洛谷 P2453 [SDOI2006]最短距离
    洛谷 P2915 [USACO08NOV]Mixed Up Cows G
    洛谷 P2473 [SCOI2008] 奖励关
    洛谷 P3391 【模板】文艺平衡树
    洛谷 P4146 序列终结者
    洛谷 P1486 [NOI2004] 郁闷的出纳员
    洛谷 P2596 [ZJOI2006]书架
    性能测试工具Jmeter02-安装配置
  • 原文地址:https://www.cnblogs.com/lsyyy/p/11265809.html
Copyright © 2011-2022 走看看