关于整体二分时间复杂度
  • 板块灌水区
  • 楼主EEchoyukii
  • 当前回复2
  • 已保存回复2
  • 发布时间2022/4/23 15:23
  • 上次更新2023/10/28 03:03:24
查看原帖
关于整体二分时间复杂度
212833
EEchoyukii楼主2022/4/23 15:23

如果值域到 1e9 这样的大数,不离散化的情况下,判断操作序列中是否还有询问这样的方法复杂度还对吗。这样写了几个题都能过的样子。

P2617 的代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
inline int read(){
	register int x=0,v=0,ch=getchar();
	while('0'>ch || ch>'9'){
		if(ch=='-')v=1;
		ch=getchar();
	}
	while('0'<=ch && ch<='9'){
		x=x*10+(ch^'0');
		ch=getchar();
	}
	return v?-x:x;
}
const int MAX=1e5+5;
int n,a[MAX],m;
struct OPT{
	int opt,l,r,v,id;
}q[MAX+MAX+MAX],q1[MAX+MAX+MAX],q2[MAX+MAX+MAX];
int ans[MAX];

int C[MAX];
inline void add(int x,int v){
	for(register int i=x;i<=n;i+=(i&-i))C[i] += v; 
}
inline int query(int x){
	int ret=0;
	for(register int i=x;i;i-=(i&-i))ret += C[i];
	return ret;
}
void solve(int l,int r,int L,int R){
	if(l>r || L>R)return ;
	if(l==r){
		for(register int i=L;i<=R;++i)if(q[i].opt == 1) ans[q[i].id] = l;
		return ;
	}
	int mid=l+r>>1,top1=0,top2=0,c1=0,c2=0;
	for(register int i=L;i<=R;++i){
		if(q[i].opt == 1){ 
			int ret = query(q[i].r) - query(q[i].l - 1);
			if(q[i].v <= ret){
				q1[++top1] = q[i];
				++c1;
			}else {
				q2[++top2] = q[i];
				q2[top2].v -= ret;
				++c2;
			}
		}else {
			if(q[i].v <= mid){
				add(q[i].l,q[i].id);
				q1[++top1] = q[i];
			}else q2[++top2] = q[i];
		}
	}
	for(register int i=1;i<=top1;++i)
		if(q1[i].opt == 2) add(q1[i].l,-q1[i].id);
	for(register int i=1;i<=top1;++i)q[L+i-1] = q1[i];
	for(register int i=1;i<=top2;++i)q[L+i+top1-1] = q2[i];
	if(c1)solve(l,mid,L,L+top1-1); // 就在这里判断一下
	if(c2)solve(mid+1,r,L+top1,R);
}
signed main(){
	n=read(),m=read();
	int top=0,tim=0;
	for(register int i=1;i<=n;++i)a[i]=read(),q[++top] = (OPT){2,i,-1,a[i],1};
	char s[3];
	for(register int i=1;i<=m;++i){
		int l,r,k;scanf("%s",s);
		if(s[0]=='Q')l=read(),r=read(),k=read(),q[++top] = (OPT){1,l,r,k,++tim};
		else {
			l=read(),k=read();
			q[++top] = (OPT){2,l,-1,a[l],-1};
			q[++top] = (OPT){2,l,-1,k,1};
			a[l] = k;
		}
	}
	solve(0,1e9,1,top);
	for(register int i=1;i<=tim;++i)printf("%d\n",ans[i]);
	return 0;
}
2022/4/23 15:23
加载中...