bzoj4262: Sum

Posted thy_asdf

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4262: Sum相关的知识,希望对你有一定的参考价值。

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4262

思路:写这题之前推荐先写uoj164

类似做法的还有HNOI2016序列(我拿莫队水过了)

也是维护一个函数性质标记

题解见:http://www.cnblogs.com/clrs97/p/4824806.html


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
typedef long long ll;
const int maxn=100010,mod=(int)1e9,maxt=maxn<<2,inf=2147483647;
using namespace std;
int n,cnt,Q,stk[maxn],top;ll ans[maxn],a[maxn];
struct querint x,l,r,id,op;q[maxn];
bool operator <(quer a,quer b)return a.x<b.x;
struct data
	ll a,b,c,d;
	void clear()a=1,b=c=d=0;
;
data operator +(data f,data g)
	return (data)
		f.a*g.a,     f.b*g.a+g.b,
		f.a*g.c+f.c, f.b*g.c+f.d+g.d
	;



void read(int &x)
    char ch;bool ok=0;
    for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    if (ok) x=-x;


struct Tsegment
	#define ls (p<<1)
	#define rs (p<<1|1)
	#define mid ((l+r)>>1)
	ll len[maxt],v[maxt],s[maxt];data tag[maxt];
	void update(int p)v[p]=v[ls]+v[rs],s[p]=s[ls]+s[rs];
	void addtag(int p,data t)
		s[p]=t.c*v[p]+t.d*len[p]+s[p];
		v[p]=t.a*v[p]+t.b*len[p];
		tag[p]=tag[p]+t;
	
	void down(int p)addtag(ls,tag[p]),addtag(rs,tag[p]),tag[p].clear();
	void build(int p,int l,int r)
		//printf("%d %d %d\\n",p,l,r);
		tag[p].clear(),len[p]=r-l+1,v[p]=s[p]=0;
		if (l==r) return;
		build(ls,l,mid),build(rs,mid+1,r);
	
	void modify(int p,int l,int r,int a,int b,data v)
		//printf("modify=%d %d %d %d %d\\n",p,l,r,a,b);
		if (l==a&&r==b)addtag(p,v);return;
		down(p);
		if (b<=mid) modify(ls,l,mid,a,b,v);
		else if (a>mid) modify(rs,mid+1,r,a,b,v);
		else modify(ls,l,mid,a,mid,v),modify(rs,mid+1,r,mid+1,b,v);
		update(p);
	
	void cover(int l,int r,ll v)modify(1,1,n,l,r,(data)0,v,0,0),addtag(1,(data)1,0,1,0);
	ll query(int p,int l,int r,int a,int b)
		//printf("query=%d %d %d %d %d\\n",p,l,r,a,b);
		if (l==a&&r==b) return s[p];
		down(p);
		if (b<=mid) return query(ls,l,mid,a,b);
		else if (a>mid) return query(rs,mid+1,r,a,b);
		else return query(ls,l,mid,a,mid)+query(rs,mid+1,r,mid+1,b);
	
	ll query(int l,int r)return query(1,1,n,l,r);
T;

void work(ll op)
	T.build(1,1,n),a[0]=inf*op,stk[top=1]=0;
	//printf("cnt=%d\\n",cnt);
	for (int i=1,j=1;i<=n;i++)
		while (top&&a[stk[top]]*op<=a[i]*op) top--;
		T.cover(stk[top]+1,i,a[i]);stk[++top]=i;
		for (;q[j].x<i;) j++;
		for (;q[j].x==i;j++)
			ans[q[j].id]+=op*T.query(q[j].l,q[j].r)*q[j].op;
			//printf("%lld\\n",T.query(q[j].l,q[j].r));
			//printf("end=%d stl=%d str=%d\\n",q[j].x,q[j].l,q[j].r);
		
	


int main()
	scanf("%d",&Q);
	for (int i=1,l1,l2,r1,r2;i<=Q;i++)
		read(l1),read(r1),read(l2),read(r2),n=max(max(r1,n),r2);
		q[++cnt]=(quer)r2,l1,r1,i,1,q[++cnt]=(quer)l2-1,l1,r1,i,-1;
	
	sort(q+1,q+1+cnt);
	//for (int i=1;i<=cnt;i++) printf("q=x=%d l=%d r=%d\\n",q[i].x,q[i].l,q[i].r);
	//printf("%d\\n",n);
	for (int i=1,t1=1023,t2=1025;i<=n;i++,t1=1ll*t1*1023%mod,t2=1ll*t2*1025%mod) a[i]=t1^t2;
	//for (int i=1;i<=n;i++) printf("%lld\\n",a[i]);
	work(1),work(-1); 
	for (int i=1;i<=Q;i++) printf("%lld\\n",ans[i]);
	return 0;

以上是关于bzoj4262: Sum的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ4262: Sum

BZOJ 4262 线段树+期望

bzoj4262

HDU 4262 Juggler

BZOJ3944Sum(杜教筛)

bzoj4176