邝斌的模板就是好用一打上去就对了,对树状数组也有了初步的了解,主席树相当于N+1课线段树,每颗线段树维护的是数组元素的前缀和或者后缀和,根据映射关系,返回相应的下标,然后取的其值,好吧,初步就是这样,但为什么,邝斌的模板过了,我自己手敲的结构体类型的就 错了,心累,留着吧,以后彻底弄清楚了我再回来解决你。真的服气。
AC代码(邝斌神代码后缀和):
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define siz 100005
#define LL int
using namespace std;
int n,q,tot,m;
int a[siz],t[siz];
int T[siz],lson[siz*30],rson[siz*30],c[siz*30];
void Init_hash(){
for(int i=1;i<=n;i++){
t[i]=a[i];
}
sort(t+1,t+1+n);
m=unique(t+1,t+1+n)-t-1;
}
int build(int l,int r){
int root=tot++;
c[root]=0;
if(l!=r){
int mid=(l+r)>>1;
lson[root]=build(l,mid);
rson[root]=build(mid+1,r);
}
return root;
}
int hash(int x){
return lower_bound(t+1,t+1+m,x)-t;
}
int updata(int root,int pos,int val){
int newroot = tot++,tmp=newroot;
c[newroot] = c[root] + val;
int l=1,r=m;
while(l<r){
int mid = (l+r)>>1;
if(pos <= mid){
lson[newroot] = tot++;rson[newroot] = rson[root];
newroot= lson[newroot];root=lson[root];
r=mid;
}
else{
rson[newroot]= tot++;lson[newroot]=lson[root];
newroot=rson[newroot];root=rson[root];
l=mid+1;
}
c[newroot] = c[root]+val;
}
return tmp;
}
int query(int left_root,int right_root,int k){
int l=1,r=m;
while(l<r){
int mid=(l+r)>>1;
if(c[lson[left_root]]-c[lson[right_root]]>=k){
r=mid;
left_root=lson[left_root];
right_root=lson[right_root];
}
else{
l=mid+1;
k-=c[lson[left_root]]-c[lson[right_root]];
left_root=rson[left_root];
right_root=rson[right_root];
}
}
return l;
}
void solve(){
tot=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
Init_hash();
//for(int i=1;i<=n;i++){
// cout<<t[i]<<"^^^^"<<endl;
// }
// cout<<m<<"----"<<endl;
T[n+1]=build(1,m);
//cout<<tot<<" "<<m<<endl;
for(int i=n;i>=1;i--){
int pos =hash(a[i]);
// cout<<pos<<endl;
T[i]= updata(T[i+1],pos,1);
}
while(q--){
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
int index=query(T[l],T[r+1],k);
int ans=t[index];
printf("%d\n",ans);
}
}
int main()
{
while(~scanf("%d %d",&n,&q)){
solve();
}
return 0;
}
自己很二的过不了的代码:(错误已找到,build里的l我打成了一个1,所以就耗了我一个上午的时间?这么多树,都不好调试。。服了)
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define siz 100005
using namespace std;
struct node{
int ls,rs;
int c;
}rt[siz*30];
int arr[siz],trr[siz],T[siz];
int n,q,tot,m;
void Init_hash(){
for(int i=1;i<=n;i++){
trr[i]=arr[i];
}
sort(trr+1,trr+n+1);
m=unique(trr+1,trr+1+n)-trr-1;
}
int build(int l,int r){
int root=tot++;
rt[root].c=0;
if(l!=r){
int mid=(l+r)>>1;
rt[root].ls=build(1,mid);
rt[root].rs=build(mid+1,r);
}
return root;
}
int hashx(int x){
return lower_bound(trr+1,trr+1+m,x)-trr;
}
int updata(int root,int pos,int val){
int newroot=tot++,tmp=newroot;
rt[newroot].c=rt[root].c+val;
int l=1,r=m;
while(l<r){
int mid=(l+r)>>1;
if(pos<=mid){
rt[newroot].ls=tot++;
rt[newroot].rs=rt[root].rs;
newroot=rt[newroot].ls;
root=rt[root].ls;
//rt[newroot].c
r=mid;
}
else{
rt[newroot].rs=tot++;
rt[newroot].ls=rt[root].ls;
newroot=rt[newroot].rs;
root=rt[root].rs;
l=mid+1;
}
rt[newroot].c=rt[root].c+val;
}
return tmp;
}
int query(int left_root,int right_root,int k){
int l=1,r=m;
while(l<r){
int mid=(l+r)>>1;
//int le=
if((rt[rt[left_root].ls].c-rt[rt[right_root].ls].c)>=k){
r=mid;
left_root=rt[left_root].ls;
right_root=rt[right_root].ls;
}
else{
l=mid+1;
k-=(rt[rt[left_root].ls].c-rt[rt[right_root].ls].c);
left_root=rt[left_root].rs;
right_root=rt[right_root].rs;
}
}
return l;
}
int main()
{
int cas;
/// scanf("%d",&cas);
// while(cas--){
while(~scanf("%d %d",&n,&q)){
tot=0;
memset(T,0,sizeof(T));
memset(rt,0,sizeof(rt));
for(int i=1;i<=n;i++){
scanf("%d",&arr[i]);
}
//cout<<"&&"<<endl;
Init_hash();
// cout<<1<<endl;
T[n+1]=build(1,m);
for(int i=n;i>=1;i--){
int pos=hashx(arr[i]);
T[i]=updata(T[i+1],pos,1);
}
/* for(int i=1;i<=n;i++){
printf("%d ",rt[T[i]].c);
}
cout<<endl;*/
//cout<<1<<endl;
while(q--){
int l,r,k;
scanf("%d %d %d",&l,&r,&k);
int inde=query(T[l],T[r+1],k);
int ans=trr[inde];
printf("%d\n",ans);
}
}
return 0;
}
感觉没啥区别呀,就是过不了,就是过不了,真的气!