Description

 

Input

第一行一个数 t,表示询问组数。
第一行一个数 t,表示询问组数。
接下来 t 行,每行四个数 l_1, r_1, l_2, r_2。
 

Output

一共 t 行,每行一个数 Sum。

Sample Input

4
1 3 5 7
2 4 6 8
1 1 9 9
9 9 1 1

Sample Output

9322587654
9025304064
1065645568
0

HINT

1<=t<=40000,1<=L1<=R1<=10^5,1<=L2<=R2<=10^5

因为数组是随机生成的,所以有一个经典的结论,固定起点或终点的线段的max-min期望有O(logn)种情况。
然后我们就可以把不相交的询问左右各分成logn段(每段max-min不同),然后用log^2n的时间内合并答案,具体见code中的solve(int l1,int r1,int l2,int r2)函数。
至于相交的询问可以容斥一下转化成不相交的询问和区间相同的询问,后者套一下线段树就可以了。
时间复杂度为O(Nlog^2N)-O(log^3N)。
#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
const int BufferSize=1<<16;
char buffer[BufferSize],*head,*tail;
inline char Getchar() {
if(head==tail) {
int l=fread(buffer,1,BufferSize,stdin);
tail=(head=buffer)+l;
}
return *head++;
}
inline int read() {
int x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
typedef long long ll;
const int maxn=200010;
const int mod=1000000000;
int A[maxn],Lmin[maxn],Rmin[maxn],Lmax[maxn],Rmax[maxn];
int S[maxn],Log[maxn],maxv[20][maxn],minv[20][maxn];
void init(int n) {
Log[0]=-1;
rep(i,1,n) Log[i]=Log[i>>1]+1,maxv[0][i]=minv[0][i]=A[i];
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+(1<<j)-1<=n;i++) {
maxv[j][i]=max(maxv[j-1][i],maxv[j-1][i+(1<<j-1)]);
minv[j][i]=min(minv[j-1][i],minv[j-1][i+(1<<j-1)]);
}
}
void query(int l,int r,int& mx,int& mn) {
if(l>r) mx=-1,mn=2147483647;
else {
int k=Log[r-l+1];
mx=max(maxv[k][l],maxv[k][r-(1<<k)+1]);
mn=min(minv[k][l],minv[k][r-(1<<k)+1]);
}
}
struct Line {
int l,r,mx,mn;
}L1[maxn],L2[maxn];
ll solve(int l1,int r1,int l2,int r2) {
if(l1>r1||l2>r2) return 0;
int mx,mn;query(r1,l2,mx,mn);ll ans=0;
int p,pmin,pmax,c1=0,c2=0;
pmin=r1;pmax=r1;p=r1;
while(p>=l1) {
int nxt=max(l1-1,max(Lmin[pmin],Lmax[pmax]));
L1[++c1]=(Line){nxt+1,p,A[pmax],A[pmin]};
p=nxt;if(A[p]>A[pmax]) pmax=p;else pmin=p;
}
pmin=l2;pmax=l2;p=l2;
while(p<=r2) {
int nxt=min(r2+1,min(Rmin[pmin],Rmax[pmax]));
L2[++c2]=(Line){p,nxt-1,A[pmax],A[pmin]};
p=nxt;if(A[p]>A[pmax]) pmax=p;else pmin=p;
}
rep(i,1,c1) rep(j,1,c2) ans+=(ll)(L1[i].r-L1[i].l+1)*(L2[j].r-L2[j].l+1)*(max(mx,max(L1[i].mx,L2[j].mx))-min(mn,min(L1[i].mn,L2[j].mn)));
return ans;
}
struct Node {
int l,r;ll sumv;
Node operator + (const Node& b) const {
Node c;c.l=l;c.r=b.r;
c.sumv=sumv+b.sumv+solve(l,r,b.l,b.r);
return c;
}
}T[maxn<<2],ans;
void build(int o,int l,int r) {
if(l==r) T[o].l=T[o].r=l,T[o].sumv=0;
else {
int mid=l+r>>1,lc=o<<1,rc=lc|1;
build(lc,l,mid);build(rc,mid+1,r);
T[o]=T[lc]+T[rc];
}
}
int flag;
void query(int o,int l,int r,int ql,int qr) {
if(ql<=l&&r<=qr) {
if(!flag) ans=T[o],flag=1;
else ans=ans+T[o];
}
else {
int mid=l+r>>1,lc=o<<1,rc=lc|1;
if(ql<=mid) query(lc,l,mid,ql,qr);
if(qr>mid) query(rc,mid+1,r,ql,qr);
}
}
int main() {
ll xp1=1,xp2=1;
rep(i,1,100000) {
(xp1*=1023)%=mod;
(xp2*=1025)%=mod;
A[i]=xp1^xp2;
}
init(100000);
int top=1;S[top]=0;A[0]=-1;
rep(i,1,100000) {
while(top&&A[i]<=A[S[top]]) top--;
Lmin[i]=S[top];S[++top]=i;
}
top=1;S[top]=0;A[0]=2147483647;
rep(i,1,100000) {
while(top&&A[i]>=A[S[top]]) top--;
Lmax[i]=S[top];S[++top]=i;
}
top=1;S[top]=100001;A[100001]=-1;
dwn(i,100000,1) {
while(top&&A[i]<=A[S[top]]) top--;
Rmin[i]=S[top];S[++top]=i;
}
top=1;S[top]=100001;A[100001]=2147483647;
dwn(i,100000,1) {
while(top&&A[i]>=A[S[top]]) top--;
Rmax[i]=S[top];S[++top]=i;
}
build(1,1,100000);
int T=read();
while(T--) {
int l1=read(),r1=read(),l2=read(),r2=read();
l2=max(l2,l1);r1=min(r1,r2);flag=0;
if(r2<l1) puts("0");
else if(r1>=l2) {
query(1,1,100000,l2,r1);
printf("%lld\n",ans.sumv+solve(l1,r1,r1+1,r2)+solve(l1,l2-1,l2,r1));
}
else printf("%lld\n",solve(l1,r1,l2,r2));
}
return 0;
}

  

BZOJ4262: Sum的更多相关文章

  1. 【BZOJ4262】Sum 单调栈+线段树

    [BZOJ4262]Sum Description Input 第一行一个数 t,表示询问组数. 第一行一个数 t,表示询问组数. 接下来 t 行,每行四个数 l_1, r_1, l_2, r_2. ...

  2. LeetCode - Two Sum

    Two Sum 題目連結 官網題目說明: 解法: 從給定的一組值內找出第一組兩數相加剛好等於給定的目標值,暴力解很簡單(只會這樣= =),兩個迴圈,只要找到相加的值就跳出. /// <summa ...

  3. Leetcode 笔记 113 - Path Sum II

    题目链接:Path Sum II | LeetCode OJ Given a binary tree and a sum, find all root-to-leaf paths where each ...

  4. Leetcode 笔记 112 - Path Sum

    题目链接:Path Sum | LeetCode OJ Given a binary tree and a sum, determine if the tree has a root-to-leaf ...

  5. POJ 2739. Sum of Consecutive Prime Numbers

    Sum of Consecutive Prime Numbers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20050 ...

  6. BZOJ 3944 Sum

    题目链接:Sum 嗯--不要在意--我发这篇博客只是为了保存一下杜教筛的板子的-- 你说你不会杜教筛?有一篇博客写的很好,看完应该就会了-- 这道题就是杜教筛板子题,也没什么好讲的-- 下面贴代码(不 ...

  7. [LeetCode] Path Sum III 二叉树的路径和之三

    You are given a binary tree in which each node contains an integer value. Find the number of paths t ...

  8. [LeetCode] Partition Equal Subset Sum 相同子集和分割

    Given a non-empty array containing only positive integers, find if the array can be partitioned into ...

  9. [LeetCode] Split Array Largest Sum 分割数组的最大值

    Given an array which consists of non-negative integers and an integer m, you can split the array int ...

随机推荐

  1. 将Vuforia程序发布到Windows10系统的基本流程

    最新博客地址已转到: http://blog.csdn.net/zzlyw?viewmode=contents   ------------------------------------------ ...

  2. css中的负边距

    css中的负边距(negative margin)是布局中的一个常用技巧,只要运用得合理常常会有意想不到的效果.很多特殊的css布局方法都依赖于负边距,所以掌握它的用法对于前端的同学来说,那是必须的. ...

  3. 枚举扩展方法获取枚举Description

    枚举扩展方法 /// <summary> /// 扩展方法,获得枚举的Description /// </summary> /// <param name="v ...

  4. 360随身wifi在win10中连不上网络

    找到服务"Wired AutoConfig"和"WLAN AutoConfig"项,点击"启动"按钮,确保使其正常启动. 讲本地网卡共享到移 ...

  5. HTML DOM Event 对象

    var event;if (document.createEvent){event = document.createEvent("HTMLEvents");event.initE ...

  6. 自定义注解之运行时注解(RetentionPolicy.RUNTIME)

    对注解概念不了解的可以先看这个:Java注解基础概念总结 前面有提到注解按生命周期来划分可分为3类: 1.RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成clas ...

  7. toArray(),toJson(),hidden([ ]),visible([ ])

    toArray() 转换为数组,hidden()不输出的字段 public function index(){ $user = model('User'); $data = $user::)-> ...

  8. STM8 AWU超低功耗模式

    每次唤醒AWU 中断标志一定要清除 __interrupt void AWU_IRQHandler(void) { AWU->CSR = AWU->CSR; /* 清除更新中断标志位 */ ...

  9. 移动端下拉刷新、加载更多插件dropload.js(基于jQuery/Zepto)[转]

    使用方法 引用css和js <link rel="stylesheet" href="../dist/dropload.min.css"> < ...

  10. XML 特殊字符

    XML转义字符 以下为XML标志符的数字和字符串转义符 "     (" 或 ") '     (' 或 &apos;) &     (& 或 & ...