传送门: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 quer{int 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;
}