求助,狂T不止
查看原帖
求助,狂T不止
91736
RPChe_楼主2021/5/2 09:11

写的是树状数组套线段树,就是两个log啊,但是就是T/kk

#include<bits/stdc++.h>
#define rep(i,a,b) for(R int i=a;i<=b;i++)
#define R register
#define endl putchar('\n')
const int N=5000005,inf=2147483647;
using namespace std;

int n,m,rt[N],sq[N],tot,a[N],tl[N],tr[N],cl,cr;
struct option {int op,l,r,k,ans;} q[N];

struct segment_tree {
	struct node {
		int ls,rs,sm;
		#define ls(x) nod[x].ls
		#define rs(x) nod[x].rs
		#define sm(x) nod[x].sm
	} nod[N<<4];
	int cnt;
	#define mid ((l+r)>>1)
	
	void add(int &k,int l,int r,int x,int v) {
		if(!k) k=++cnt;
		sm(k)+=v;
		if(l==r) return;
		if(x<=mid) add(ls(k),l,mid,x,v);
		else add(rs(k),mid+1,r,x,v);
	}
	int query(int k,int l,int r,int x,int y) {
		if(!k||x>y) return 0;
		if(x<=l&&r<=y) return sm(k);
		int res=0;
		if(x<=mid) res+=query(ls(k),l,mid,x,y);
		if(y>mid) res+=query(rs(k),mid+1,r,x,y);
		return res;
	}
	int query1(int l,int r,int k) {
		if(l==r) return sq[l];
		int sm=0;
		rep(i,1,cr) sm+=sm(ls(tr[i]));
		rep(i,1,cl) sm-=sm(ls(tl[i]));
		if(k<=sm) {
			rep(i,1,cr) tr[i]=ls(tr[i]);
			rep(i,1,cl) tl[i]=ls(tl[i]);
			return query1(l,mid,k);
		} else {
			rep(i,1,cr) tr[i]=rs(tr[i]);
			rep(i,1,cl) tl[i]=rs(tl[i]);
			return query1(mid+1,r,k-sm);
		}
	}
} smt;

#define lowbit(x) (x&-x)
int rank(int l,int r,int k) {
	int res=0;k=lower_bound(sq+1,sq+tot+1,k)-sq-1,l--;
	for(R int i=r;i>=1;i-=lowbit(i)) res+=smt.query(rt[i],1,tot,1,k);
	for(R int i=l;i>=1;i-=lowbit(i)) res-=smt.query(rt[i],1,tot,1,k);
	return res+1;
}
int find(int l,int r,int k) {
	for(R int i=r;i>=1;i-=lowbit(i)) tr[++cr]=rt[i];
	for(R int i=l-1;i>=1;i-=lowbit(i)) tl[++cl]=rt[i];
	return smt.query1(1,tot,k);
}
void modify(int p,int k) {
	for(R int i=p;i<=n;i+=lowbit(i)) smt.add(rt[i],1,tot,a[p],-1);
	a[p]=lower_bound(sq+1,sq+tot+1,k)-sq;
	for(R int i=p;i<=n;i+=lowbit(i)) smt.add(rt[i],1,tot,a[p],1);
}
int lower(int l,int r,int k) {
	k=rank(l,r,k);
	return k==1?-inf:find(l,r,k-1);
}
int upper(int l,int r,int k) {
	k=rank(l,r,k+1);
	return k==r-l+2?inf:find(l,r,k);
}

void init() {
	sort(sq+1,sq+tot+1);
	tot=unique(sq+1,sq+tot+1)-sq-1;
	rep(i,1,n) {
		a[i]=lower_bound(sq+1,sq+tot+1,a[i])-sq;
		for(R int j=i;j<=n;j+=lowbit(j)) smt.add(rt[j],1,tot,a[i],1);
	}
}

void solve() {
	rep(i,1,m) {
		switch(q[i].op) {
			case 1: printf("%d\n",rank(q[i].l,q[i].r,q[i].k)); break;
			case 2: printf("%d\n",find(q[i].l,q[i].r,q[i].k)); break;
			case 3: modify(q[i].l,q[i].k); break;
			case 4: printf("%d\n",lower(q[i].l,q[i].r,q[i].k)); break;
			case 5: printf("%d\n",upper(q[i].l,q[i].r,q[i].k)); break;
		}
	}
}

void file() {
	freopen("P3380_2.in","r",stdin);
	freopen("P3380.out","w",stdout);
}

int main() {
//	file();
	scanf("%d%d",&n,&m);
	rep(i,1,n) scanf("%d",&a[i]),sq[++tot]=a[i];
	rep(i,1,m) {
		scanf("%d",&q[i].op);
		if(q[i].op==3) {
			scanf("%d%d",&q[i].l,&q[i].k);
			sq[++tot]=q[i].k;
		} else scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k);
	}
	init();
	solve();
	return 0;
}
2021/5/2 09:11
加载中...