权值线段树套区间线段树
一开始没标记永久化T,
然后标记永久化+外层权值线段树1~1e18还是T了
队里大佬帮我卡了好久的常最后还是差一个点
最后没办法我把外层权值线段树改成1~1e10就A了qwq
/**************************************************************
Problem: 3110
User: syh0313
Language: C++
Result: Accepted
Time:10740 ms
Memory:396644 kb
****************************************************************/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#define lch a[n].lc
#define rch a[n].rc
using
namespace
std;
const
int
maxn=100010;
const
long
long
ma=1e10;
int
nn,m,topt,cnt,root[4*maxn],ro;
struct
da{
int
lc,rc,tag;
long
long
si;}a[200*maxn];
struct
daa{
int
lc,rc;}b[4*maxn];
void
tree_add_2(
int
&n,
int
L,
int
R,
int
l,
int
r)
{
if
(!n) n=++cnt;
if
(L==l && R==r) {a[n].si+=r-l+1; ++a[n].tag;
return
;}
int
mid=(L+R)>>1;
if
(r<=mid) tree_add_2(lch,L,mid,l,r);
else
if
(l>=mid+1) tree_add_2(rch,mid+1,R,l,r);
else
tree_add_2(lch,L,mid,l,mid),tree_add_2(rch,mid+1,R,mid+1,r);
a[n].si=a[lch].si+a[rch].si+a[n].tag*(R-L+1);
}
void
tree_add(
int
&n,
long
long
l,
long
long
r,
long
long
lc,
int
ll,
int
rr)
{
if
(!n) n=++topt;
tree_add_2(root[n],1,nn,ll,rr);
if
(l==r)
return
;
long
long
mid=(l+r)>>1;
if
(lc<=mid) tree_add(b[n].lc,l,mid,lc,ll,rr);
else
tree_add(b[n].rc,mid+1,r,lc,ll,rr);
}
long
long
qsum(
int
n,
int
L,
int
R,
int
l,
int
r,
int
kk)
{
if
(!n)
return
1ll*kk*(r-l+1);
if
(L==l && R==r) {
return
a[n].si+1ll*kk*(r-l+1);}
kk+=a[n].tag;
int
mid=(L+R)>>1;
if
(r<=mid)
return
qsum(lch,L,mid,l,r,kk);
else
if
(l>=mid+1)
return
qsum(rch,mid+1,R,l,r,kk);
else
return
qsum(lch,L,mid,l,mid,kk)+qsum(rch,mid+1,R,mid+1,r,kk);
}
long
long
qury(
int
n,
long
long
l,
long
long
r,
int
ll,
int
rr,
long
long
k)
{
if
(l==r)
return
r;
long
long
mid=(l+r)>>1,si2=0;
if
(b[n].rc) si2=qsum(root[b[n].rc],1,nn,ll,rr,0);
if
(k<=si2)
return
qury(b[n].rc,mid+1,r,ll,rr,k);
else
return
qury(b[n].lc,l,mid,ll,rr,k-si2);
}
inline
int
read()
{
int
xx=0,ff=1;
char
c=
getchar
();
while
(c<
'0'
|| c>
'9'
) {
if
(c==
'-'
) ff=-1; c=
getchar
();}
while
(c>=
'0'
&& c<=
'9'
) {xx=(xx<<1)+(xx<<3)+c-
'0'
; c=
getchar
();}
return
xx*ff;
}
inline
long
long
readl()
{
long
long
xx=0,ff=1;
char
c=
getchar
();
while
(c<
'0'
|| c>
'9'
) {
if
(c==
'-'
) ff=-1; c=
getchar
();}
while
(c>=
'0'
&& c<=
'9'
) {xx=(xx<<1)+(xx<<3)+c-
'0'
; c=
getchar
();}
return
xx*ff;
}
int
main()
{
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
nn=read(); m=read();
while
(m--)
{
int
ff,aa,bb;
long
long
cc;
ff=read(); aa=read(); bb=read(); cc=readl();
if
(ff==1) tree_add(ro,1,ma,cc,aa,bb);
else
printf
(
"%lld\n"
,qury(ro,1,ma,aa,bb,cc));
}
return
0;
}