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
接下来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
裸线段树套线段树:题解给的是外层权值线段树,内层区间线段树。我的理解是,外层权值线段树[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
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 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("%d\n",M-quaryX(v,b)); } } return 0; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。