4262: Sum
Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 66 Solved: 29
[ Submit][ Status][ Discuss]
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
1 3 5 7
2 4 6 8
1 1 9 9
9 9 1 1
Sample Output
9322587654
9025304064
1065645568
0
9025304064
1065645568
0
HINT
1<=t<=40000,1<=L1<R1<=10^5,1<=L2<=R2<=10^5
Source
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<bitset>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
const int maxn = 1E5 + 10;
const int T = 4;
typedef long long LL;
const LL mo = 1000000000;
struct Query{
int l,r,g,num,typ; Query(){}
Query(int l,int r,int g,int num,int typ): l(l),r(r),g(g),num(num),typ(typ){}
bool operator < (const Query &b) const
{
return g < b.g;
}
}Q[maxn];
int m,N,tot,f[maxn],L[maxn][2];
LL ans[maxn],len[maxn*T],val[maxn*T],sum[maxn*T],a[maxn*T],b[maxn*T],c[maxn*T],d[maxn*T];
stack <int> s;
int Add(LL x,LL y) {return (x + y + mo)%mo;}
int Mul(LL x,LL y) {return x*y%mo;}
void Build(int o,int l,int r)
{
len[o] = r - l + 1;
a[o] = 1; b[o] = c[o] = d[o] = 0;
sum[o] = val[o] = 0;
if (l == r) return;
int mid = (l + r) >> 1;
Build(o<<1,l,mid);
Build(o<<1|1,mid+1,r);
}
void Work(int x,int y)
{
LL A,B,C,D;
B = b[x] + a[x]*b[y];
A = a[x]*a[y];
D = d[x] + b[y]*c[x] + d[y];
C = a[y]*c[x] + c[y];
a[y] = A; b[y] = B;
c[y] = C; d[y] = D;
}
void pushdown(int o,int l,int r)
{
if (a[o] == 1 && !b[o] && !c[o] && !d[o]) return;
LL VAL = a[o]*val[o] + b[o]*len[o];
LL SUM = sum[o] + c[o]*val[o] + d[o]*len[o];
val[o] = VAL; sum[o] = SUM;
if (l == r) {a[o] = 1; b[o] = c[o] = d[o] = 0; return;}
Work(o,o<<1); Work(o,o<<1|1);
a[o] = 1; b[o] = c[o] = d[o] = 0;
}
void Modify(int o,int l,int r,int ml,int mr,int x)
{
if (ml <= l && r <= mr)
{
a[0] = 0; b[0] = x;
c[0] = 0; d[0] = 0;
Work(0,o);
pushdown(o,l,r);
return;
}
pushdown(o,l,r);
int mid = (l + r) >> 1;
if (ml <= mid) Modify(o<<1,l,mid,ml,mr,x); else pushdown(o<<1,l,mid);
if (mr > mid) Modify(o<<1|1,mid+1,r,ml,mr,x); else pushdown(o<<1|1,mid+1,r);
val[o] = val[o<<1] + val[o<<1|1];
sum[o] = sum[o<<1] + sum[o<<1|1];
}
LL query(int o,int l,int r,int ql,int qr)
{
pushdown(o,l,r);
if (ql <= l && r <= qr) return sum[o];
int mid = (l + r) >> 1; LL ret = 0;
if (ql <= mid) ret += query(o<<1,l,mid,ql,qr);
if (qr > mid) ret += query(o<<1|1,mid+1,r,ql,qr);
return ret;
}
void Pre_Work()
{
for (int i = 1,A = 1023,B = 1025; i <= N; i++)
f[i] = A^B,A = Mul(A,1023),B = Mul(B,1025);
for (int i = N; i; i--)
{
while (!s.empty() && f[s.top()] < f[i])
L[s.top()][0] = i,s.pop();
s.push(i);
}
while (!s.empty()) L[s.top()][0] = 0,s.pop();
for (int i = N; i; i--)
{
while (!s.empty() && f[s.top()] > f[i])
L[s.top()][1] = i,s.pop();
s.push(i);
}
while (!s.empty()) L[s.top()][1] = 0,s.pop();
}
int getint()
{
char ch = getchar();
int ret = 0;
while (ch < '0' || '9' < ch) ch = getchar();
while ('0' <= ch && ch <= '9')
ret = ret*10 + ch - '0',ch = getchar();
return ret;
}
int main()
{
//freopen("4262.in","r",stdin);
//freopen("4262.out","w",stdout);
m = getint();
for (int i = 1; i <= m; i++)
{
int l1,r1,l2,r2;
l1 = getint(); r1 = getint();
l2 = getint(); r2 = getint();
if (l2 > 1) Q[++tot] = Query(l1,r1,l2-1,i,-1);
Q[++tot] = Query(l1,r1,r2,i,1);
N = max(N,r2); N = max(N,r1);
}
Pre_Work();
sort(Q + 1,Q + tot + 1);
int now = 0; Build(1,1,N);
for (int i = 1; i <= tot; i++)
{
while (now < Q[i].g)
{
++now;
Modify(1,1,N,L[now][0] + 1,now,f[now]);
a[0] = 1; b[0] = 0;
c[0] = 1; d[0] = 0;
Work(0,1);
}
ans[Q[i].num] += 1LL*Q[i].typ*query(1,1,N,Q[i].l,Q[i].r);
}
now = 0; Build(1,1,N);
for (int i = 1; i <= tot; i++)
{
while (now < Q[i].g)
{
++now;
Modify(1,1,N,L[now][1] + 1,now,f[now]);
a[0] = 1; b[0] = 0;
c[0] = 1; d[0] = 0;
Work(0,1);
}
ans[Q[i].num] -= 1LL*Q[i].typ*query(1,1,N,Q[i].l,Q[i].r);
}
for (int i = 1; i <= m; i++) printf("%lld\n",ans[i]);
return 0;
}