有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c
如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。
BZOJ 3110(ZJOI K大数查询-线段树套线段树)
发布时间:2020-12-14 02:39:05 所属栏目:大数据 来源:网络整理
导读:3110: [Zjoi2013]K大数查询 Time Limit:? 20 Sec?? Memory Limit:? 512 MB Submit:? 1785?? Solved:? 816 [ Submit][ Status][ Discuss] Description 有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入
3110: [Zjoi2013]K大数查询Time Limit:?20 Sec?? Memory Limit:?512 MBSubmit:?1785?? Solved:?816 [ Submit][ Status][ Discuss] DescriptionInput第一行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 Output1
2 1 HINTN,M<=50000,N,M<=50000 裸线段树套线段树:题解给的是外层权值线段树,内层区间线段树。我的理解是,外层权值线段树[L,R] 表示 插入的节点的权值,对于插入x权值的节点,我们对此节点建立一棵区间线段树,如果说我想在[a,b]区间插入x权的数,那么就是在此线段树中查找[a,b]区间使[a,b]区间value域+=b-a+1;此题可切;不过代码写的不怎么快,比标准代码慢了3倍左右,内存使用的也比较多!!谁来帮我优化!!
a<=b<=N 1操作中abs(c)<=N 2操作中abs(c)<=Maxlongint
#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 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],mid,L,R); if(R>mid) addY(rs[id],mid+1,r,R); push_up(id); } int quaryY(int id,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,r); if(L<=mid) tem += quaryY(ls[id],R); if(R>mid) tem += quaryY(rs[id],R); return tem; } void addX(int x,int id,int R){ addY(root[id],1,n,R); if(l == r) return; int mid = ( l + r ) >> 1; if(x<=mid) addX(x,id<<1,R); else addX(x,id<<1|1,R); } int quaryX(int k,int R){ if(l==r) return l; int tem = quaryY(root[id<<1],R); int mid = (l + r)>>1; if(tem>=k) return quaryX(k,R); else return quaryX(k-tem,R); } void init() { nodeID = 1; memset(root,sizeof(root)); memset(tag,sizeof(tag)); memset(ls,sizeof(ls)); memset(rs,sizeof(rs)); memset(value,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,2*M,b); else printf("%dn",M-quaryX(v,b)); } } return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |