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的主要内容,如果未能解决你的问题,请参考以下文章