3110: [Zjoi2013]K大数查询
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1785 Solved: 816
[ Submit][ Status][ Discuss]
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
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
2
1
HINT
N,M<=50000,N,M<=50000
a<=b<=N
1操作中abs(c)<=N
2操作中abs(c)<=Maxlongint
931816 | 3110 | Accepted | 314724 kb | 15624 ms | C++/Edit | 2493 B | 2015-04-13 23:06:57 |
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define N 20010900
#define M 50009
int n,m,nodeID;
int value[N],tag[N],ls[N],rs[N],root[4*M+10];
void push_up(int id) {
value[id] = 0;
value[id] += value[ls[id]];
value[id] += value[rs[id]];
}
void push_down(int id,int l,int r) {
if(tag[id] == 0) return;
if(ls[id]==0) ls[id] = ++nodeID;
if(rs[id]==0) rs[id] = ++nodeID;
int mid = ( l + r ) >> 1;
value[ls[id]] += tag[id]*(mid - l + 1);
value[rs[id]] += tag[id]*(r - mid);
tag[ls[id]] += tag[id];
tag[rs[id]] += tag[id];
tag[id] = 0;
}
void addY(int &id,int l,int r,int L,int R) {
if(id == 0) id = ++nodeID;
if(L<=l&&R>=r){ value[id] += (r-l+1); tag[id]++; return; }
int mid = ( l + r ) >> 1;
push_down(id,l,r);
if(L<=mid) addY(ls[id],l,mid,L,R);
if(R>mid) addY(rs[id],mid+1,r,L,R);
push_up(id);
}
int quaryY(int id,int l,int r,int L,int R) {
if(id == 0) return 0;
if(L<=l&&R>=r) return value[id];
int mid = ( l + r ) >> 1;
int tem = 0;
push_down(id,l,r);
if(L<=mid) tem += quaryY(ls[id],l,mid,L,R);
if(R>mid) tem += quaryY(rs[id],mid+1,r,L,R);
return tem;
}
void addX(int x,int l,int r,int id,int L,int R){
addY(root[id],1,n,L,R);
if(l == r) return;
int mid = ( l + r ) >> 1;
if(x<=mid) addX(x,l,mid,id<<1,L,R);
else addX(x,mid+1,r,id<<1|1,L,R);
}
int quaryX(int k,int l,int r,int id,int L,int R){
if(l==r) return l;
int tem = quaryY(root[id<<1],1,n,L,R);
int mid = (l + r)>>1;
if(tem>=k) return quaryX(k,l,mid,id<<1,L,R);
else return quaryX(k-tem,mid+1,r,id<<1|1,L,R);
}
void init() {
nodeID = 1;
memset(root,0,sizeof(root));
memset(tag,0,sizeof(tag));
memset(ls,0,sizeof(ls));
memset(rs,0,sizeof(rs));
memset(value,0,sizeof(value));
}
int main() {
int flag,a,b,v;
//freopen("sequence9.in","r",stdin);
//freopen("out.txt","w",stdout);
while(~scanf("%d%d",&n,&m)) {
init();
for(int i = 1;i<=m;i++) {
scanf("%d%d%d%d",&flag,&a,&b,&v);
if(flag == 1) addX(M-v,1,2*M,1,a,b);
else printf("%d\n",M-quaryX(v,1,2*M,1,a,b));
}
}
return 0;
}