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