bzoj1901

数组开小,身败名裂;

题目本身没什么可说,练习一下主席树,结果是调了3个多小时的错误,结果是数组开小了,蛤蛤~

这样的数组[3],开成了这样的[2];

//2017 1 14 by chad
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<ctime>
#include<algorithm>
using namespace std;
#define LL long long
#define FILE "dealing"
#define up(i,j,n) for(int i=(j);(i)<=(n);i=(i+1))
namespace IO{
	char buf[1<<20],*fs,*ft;
	int gc(){return ((fs==ft)&&(fs=(buf+fread(buf,1<<20,1,stdin)),fs==ft))?-1:*fs++;}
	int read(){
		int x=0,f=1,ch=getchar();
		while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
		while(ch<='9'&&ch>='0')x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
		return f*x;
	}
}using namespace IO;
const int maxn=201000;
int n,m;
int a[maxn],ch[maxn],l[maxn],r[maxn],k[maxn],c[maxn],t[maxn],D[maxn],w[maxn];
struct node{
	int flag,v,id;
	bool operator<(const node& b)const{return v<b.v;}
}e[maxn];
int cnt=0;
namespace tree{
	const int maxn=101000<<5;
	#define mid ((l+r)>>1)
	int rt[maxn],c[maxn][2],d,sum[maxn],SUM=0;
	void updata(int o){sum[o]=sum[c[o][0]]+sum[c[o][1]];}
	void insert(int pre,int& o,int key,int l,int r){
		if(!o)o=++SUM;
		if(l==r){sum[o]=1;return;}
		d=key>mid;
		c[o][d^1]=c[pre][d^1];
		insert(c[pre][d],c[o][d],key,d?mid+1:l,d?r:mid);
		updata(o);
	}
	void init(int *a,int n,int cnt){up(i,1,n)insert(rt[i-1],rt[i],a[i],1,cnt);}
	int q[3][5000],L1=0,L2=0,s[maxn],rot[maxn],ch[maxn][2],tot=0;
	int lowbit(int x){return x&-x;}
	void update(int o){s[o]=s[ch[o][0]]+s[ch[o][1]];}
	void Change(int key,int l,int r,int add,int& o){
		if(!o)o=++tot;
		if(l==r){s[o]+=add;return;}
		d=key>mid;
		Change(key,d?mid+1:l,d?r:mid,add,ch[o][d]);
		update(o);
	}
	void change(int pos,int y,int tt){
		int i=pos;
		while(i<=n)Change(w[pos],1,cnt,-1,rot[i]),i+=lowbit(i);i=pos;
		while(i<=n)Change(D[y],1,cnt,1,rot[i]),i+=lowbit(i);i=pos;
		a[pos]=tt;w[pos]=D[y];
	}
	int u,v;
	int query(int x,int y,int l,int r,int k){
		if(l==r)return l;
		u=v=0;
		up(i,1,L1)u+=s[ch[q[1][i]][0]];
		up(i,1,L2)v+=s[ch[q[2][i]][0]];
		if(sum[c[y][0]]-sum[c[x][0]]+v-u>k){
			up(i,1,L1)q[1][i]=ch[q[1][i]][0];
			up(i,1,L2)q[2][i]=ch[q[2][i]][0];
			return query(c[x][0],c[y][0],l,mid,k);
		}
		else {
			up(i,1,L1)q[1][i]=ch[q[1][i]][1];
			up(i,1,L2)q[2][i]=ch[q[2][i]][1];
			return query(c[x][1],c[y][1],mid+1,r,k-(sum[c[y][0]]-sum[c[x][0]]+v-u));
		}
	}
	int Query(int k,int l,int r){
		L1=L2=0;
		int x=l-1;while(x){q[1][++L1]=rot[x];x-=lowbit(x);}
		x=r;while(x)q[2][++L2]=rot[x],x-=lowbit(x);
		return query(rt[l-1],rt[r],1,cnt,k-1);
	}
};
int main(){
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);
	n=read(),m=read();
	up(i,1,n)e[++cnt].v=a[i]=read(),e[cnt].flag=1,e[cnt].id=i;
	up(i,1,m){
		scanf(" %c",&ch[i]);
		if(ch[i]=='C')c[i]=read(),t[i]=read(),e[++cnt].flag=2,e[cnt].v=t[i],e[cnt].id=i;
		else l[i]=read(),r[i]=read(),k[i]=read();
	}
	sort(e+1,e+cnt+1);
	up(i,1,cnt){
		if(e[i].flag==1)w[e[i].id]=i;
		else D[e[i].id]=i;
	}
	tree::init(w,n,cnt);
	up(i,1,m){
		if(ch[i]=='Q')printf("%d\n",e[tree::Query(k[i],l[i],r[i])].v);
		else tree::change(c[i],i,t[i]);
	}
	return 0;
}

  

posted @ 2017-01-14 17:07  CHADLZX  阅读(...)  评论(...编辑  收藏