标签:lowbit space 位置 tick pos should targe content follow
输入n,再输入n个操作,操作有四种
0, Insert X:插入x到序列末尾
1, query_1 L R X:在当前序列中的[l,r]区间找第x小的数。
2, query_2 X:在当前序列中,输出X是第几小的数。
3, query_3 X:找到当前序列中第X小的数是几。
然后输出的是3种query的和。
操作1和操作3是查询区间第k小,主席树。
操作2是求排名,用树状数组或者二分。
在线转化为离线。
求Kth的主席树的模板见我之前写的:http://www.cnblogs.com/hua-dong/p/7931778.html
#include<cstdio> #include<cstdlib> #include<iostream> #include<cstring> #include<algorithm> #include<map> using namespace std; const int maxn=200010; int a[maxn],b[maxn],Innum,n;//a是位置,b是值。Innum是输入的个数,即 int cnt,ql,qr,Case=0; long long sum1,sum2,sum3; struct questions { int opt;//0,1,2,3 int x,y,k; }Qst[maxn<<1]; struct PLTree { int ch[maxn * 20][2],sum[maxn * 20],rt[maxn]; void build(int& now,int l,int r) { now = ++ cnt; sum[now] = 0; if(l == r) return ; int Mid = (l + r)>>1; build(ch[now][0],l,Mid); build(ch[now][1],Mid + 1,r); } void insert(int& now,int last,int l,int r,int pos) { now = ++ cnt; ch[now][0]=ch[last][0]; ch[now][1]=ch[last][1]; sum[now] = sum[last] + 1; if(l == r) return ; int Mid = (l+r) >> 1; if(pos <= Mid) insert(ch[now][0],ch[last][0],l,Mid,pos); else insert(ch[now][1],ch[last][1],Mid + 1,r,pos); } int query(int ss,int tt,int l,int r,int k) { if(l == r) return l; int Mid =(l + r) >> 1,tmp = sum[ch[tt][0]] - sum[ch[ss][0]]; if(k <= tmp) return query(ch[ss][0],ch[tt][0],l,Mid,k); else return query(ch[ss][1],ch[tt][1],Mid + 1,r,k - tmp); } }; PLTree P; void _init() { Innum=cnt=0; sum1=sum2=sum3=0; } void _scanf() { char chr[10]; for(int i=1;i<=n;i++){ scanf("%s",chr); if(chr[0]==‘I‘){ Qst[i].opt=0; scanf("%d",&Qst[i].x); a[++Innum]=Qst[i].x; b[Innum]=a[Innum]; } else { Qst[i].opt=chr[6]-‘0‘; if(chr[6]==‘1‘) scanf("%d%d%d",&Qst[i].x,&Qst[i].y,&Qst[i].k); else scanf("%d",&Qst[i].k); } } } void _disp() { sort(b+1,b+Innum+1); for(int i=1;i<=Innum;i++) a[i]=lower_bound(b+1,b+Innum+1,a[i])-b; } void _work() { P.build(P.rt[0],1,Innum); int nowcnt=0,ans; for(int i=1;i<=n;i++){ if(Qst[i].opt==0) { nowcnt++; P.insert(P.rt[nowcnt],P.rt[nowcnt-1],1,Innum,a[nowcnt]); } else if(Qst[i].opt==1){ ans=P.query(P.rt[Qst[i].x-1],P.rt[Qst[i].y],1,Innum,Qst[i].k); sum1+=b[ans]; } else if(Qst[i].opt==2){ int L=1,R=nowcnt; while(L<=R){ int Mid=(L+R)>>1; ans=P.query(P.rt[0],P.rt[nowcnt],1,Innum,Mid); if(b[ans]==Qst[i].k) { sum2+=Mid; break; } else if(b[ans]<Qst[i].k) L=Mid+1; else R=Mid-1; } } else { ans=P.query(P.rt[0],P.rt[nowcnt],1,Innum,Qst[i].k); sum3+=b[ans]; } } printf("Case %d:\n",++Case); printf("%lld\n%lld\n%lld\n",sum1,sum2,sum3); } int main() { while(~scanf("%d",&n)){ _init(); _scanf();//输入 _disp();//离散 _work(); } return 0; }
#include<cstdio> #include<cstdlib> #include<iostream> #include<cstring> #include<algorithm> #include<map> using namespace std; const int maxn=200010; int a[maxn],b[maxn],Innum,n;//a是位置,b是值。Innum是操作为输入的个数,即 int cnt,ql,qr,Case=0; long long sum1,sum2,sum3; int c[maxn<<1]; int lowbit(int x ) { return x&-x; } void add( int x ) { while(x < Innum){ c[x]++; x += lowbit ( x ); } } int sum(int x ) { int ret = 0; while (x){ ret += c[x]; x -= lowbit ( x ); } return ret; } struct questions { int opt;//0,1,2,3 int x,y,k; }Qst[maxn<<1]; struct PLTree { int ch[maxn * 20][2],sum[maxn * 20],rt[maxn]; void build(int& now,int l,int r) { now = ++ cnt; sum[now] = 0; if(l == r) return ; int Mid = (l + r)>>1; build(ch[now][0],l,Mid); build(ch[now][1],Mid + 1,r); } void insert(int& now,int last,int l,int r,int pos) { now = ++ cnt; ch[now][0]=ch[last][0]; ch[now][1]=ch[last][1]; sum[now] = sum[last] + 1; if(l == r) return ; int Mid = (l+r) >> 1; if(pos <= Mid) insert(ch[now][0],ch[last][0],l,Mid,pos); else insert(ch[now][1],ch[last][1],Mid + 1,r,pos); } int query(int ss,int tt,int l,int r,int k) { if(l == r) return l; int Mid =(l + r) >> 1,tmp = sum[ch[tt][0]] - sum[ch[ss][0]]; if(k <= tmp) return query(ch[ss][0],ch[tt][0],l,Mid,k); else return query(ch[ss][1],ch[tt][1],Mid + 1,r,k - tmp); } }; PLTree P; void _init() { Innum=cnt=0; sum1=sum2=sum3=0; memset(c,0,sizeof(c)); } void _scanf() { char chr[10]; for(int i=1;i<=n;i++){ scanf("%s",chr); if(chr[0]==‘I‘){ Qst[i].opt=0; scanf("%d",&Qst[i].x); a[++Innum]=Qst[i].x; b[Innum]=a[Innum]; } else { Qst[i].opt=chr[6]-‘0‘; if(chr[6]==‘1‘) scanf("%d%d%d",&Qst[i].x,&Qst[i].y,&Qst[i].k); else scanf("%d",&Qst[i].k); } } } void _disp() { sort(b+1,b+Innum+1); for(int i=1;i<=Innum;i++) a[i]=lower_bound(b+1,b+Innum+1,a[i])-b; } void _work() { P.build(P.rt[0],1,Innum); int nowcnt=0,ans; for(int i=1;i<=n;i++){ if(Qst[i].opt==0) { nowcnt++; P.insert(P.rt[nowcnt],P.rt[nowcnt-1],1,Innum,a[nowcnt]); add(a[nowcnt]); } else if(Qst[i].opt==1){ ans=P.query(P.rt[Qst[i].x-1],P.rt[Qst[i].y],1,Innum,Qst[i].k); sum1+=b[ans]; } else if(Qst[i].opt==2){ int tmp=sum(lower_bound(b+1,b+Innum+1,Qst[i].k)-b); sum2+=tmp; } else { ans=P.query(P.rt[0],P.rt[nowcnt],1,Innum,Qst[i].k); sum3+=b[ans]; } } printf("Case %d:\n",++Case); printf("%lld\n%lld\n%lld\n",sum1,sum2,sum3); } int main() { while(~scanf("%d",&n)){ _init(); _scanf();//输入 _disp();//离散 _work(); } return 0; }
标签:lowbit space 位置 tick pos should targe content follow
原文地址:http://www.cnblogs.com/hua-dong/p/7954258.html