[BZOJ3110][ZJOI2013]K大數查詢
阿新 • • 發佈:2018-01-10
div gin 代碼 class clu getchar() mar 一行 zoj
2操作中c<=Maxlongint
BZOJ
Luogu
Description
有N個位置,M個操作。操作有兩種,每次操作如果是1 a b c的形式表示在第a個位置到第b個位置,每個位置加入一個數c
如果是2 a b c形式,表示詢問從第a個位置到第b個位置,第C大的數是多少。
Input
第一行N,M
接下來M行,每行形如1 a b c或2 a b c
Output
輸出每個詢問的結果
Sample Input
2 5
1 1 2 1
1 1 2 2
2 1 1 2
2 1 1 1
2 1 2 3
Sample Output
1
2
1
HINT
N,M<=50000,N,M<=50000
a<=b<=N
1操作中abs(c)<=N
sol
樹套樹題解
線段樹套線段樹,註意內層是動態開節點。
先確定內外層關系:外層表示數值,內層表示區間。(你可以試一試反過來)
那麽修改操作就是外層的單點修改,而實際上應該是單點到根的路徑上的節點的修改,即我們要修改log棵線段樹。在每個線段樹裏面是區間加1。可以直接寫標記永久化(練一波手)
查詢時在外層二分,就是常規的求第k大,只是每次算右兒子size的時候都要在右兒子那棵線段樹上查一下區間和。
外層線段樹直接用循環代替
代碼好寫得很
code
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 50005;
#define ll long long
struct segment_tree{
int ls,rs,tim;ll num;
}t[N*300];
int n,m,rt[N*16],tot;
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
void Modify(int &x,int l,int r,int ql,int qr)
{
if (!x) x=++tot;
if (l==ql&&r==qr) {t[x].tim++;return;}
t[x].num+=qr-ql+1;
int mid=l+r>>1;
if (qr<=mid) Modify(t[x].ls,l,mid,ql,qr);
else if (ql>mid) Modify(t[x].rs,mid+1,r,ql,qr);
else Modify(t[x].ls,l,mid,ql,mid),Modify(t[x].rs,mid+1,r,mid+1,qr);
}
ll Query(int x,int l,int r,int ql,int qr)
{
ll res=1ll*t[x].tim*(qr-ql+1);
if (l==ql&&r==qr) return res+t[x].num;
int mid=l+r>>1;
if (qr<=mid) return res+Query(t[x].ls,l,mid,ql,qr);
else if (ql>mid) return res+Query(t[x].rs,mid+1,r,ql,qr);
else return res+Query(t[x].ls,l,mid,ql,mid)+Query(t[x].rs,mid+1,r,mid+1,qr);
}
int main()
{
n=gi();m=gi();
while (m--)
{
int opt=gi(),a=gi(),b=gi(),c=gi(),now=1,l=1,r=n;
if (opt==1)
while (233)
{
Modify(rt[now],1,n,a,b);
if (l==r) break;
int mid=l+r>>1;
if (c<=mid) now=now<<1,r=mid;
else now=now<<1|1,l=mid+1;
}
else
while (l<r)
{
ll sum=Query(rt[now<<1|1],1,n,a,b);
int mid=l+r>>1;
if ((ll)c<=sum)
now=now<<1|1,l=mid+1;
else c-=sum,now=now<<1,r=mid;
}
if (opt==2) printf("%d\n",l);
}
return 0;
}
[BZOJ3110][ZJOI2013]K大數查詢