关于树状数组和线段树的时间复杂度
  • 板块学术版
  • 楼主Three_bodyIII
  • 当前回复7
  • 已保存回复7
  • 发布时间2024/10/21 16:30
  • 上次更新2024/10/21 19:23:24
查看原帖
关于树状数组和线段树的时间复杂度
928270
Three_bodyIII楼主2024/10/21 16:30

RT.为甚么这题我树状数组A了,线段树TLE了???
AC code:

#include <bits/stdc++.h>
#define int long long
#define lowbit(x) (x &(- x))
using namespace std;
const int N = 1e6 + 1;
int a[N], b[N], p[1000], n, m, W;
int read () {
	int num = 0, fs = 1;
	char ch = getchar ();
	while ( ( ch < '0' || ch > '9' ) && ch != '-' )	ch = getchar ();
	if ( ch == '-' )	fs = - 1, ch = getchar ();
	while ( ch >= '0' && ch <= '9' ) num = num * 10 + ch - '0', ch = getchar();
	return num * fs;
}
void write(int x) {
	if(x < 0) {
		putchar('-');
		x = - x;
	}
	if(x < 10) {
		putchar(x + '0');
		return ;
	}
	write(x / 10);
	putchar(x % 10 + '0');
}
int check(int &x, int y) {
	int ans = 0;
	while(x > y) {
		x = x - y;
		y = y * 2;
		ans ++;
	}
	return ans;
}
void Up1 (int x, int y) {
	if(x > n) return ;
	a[x] += y;
	Up1 (x + lowbit(x), y);
}
void Up2 (int x, int y) {
	if(x > n) return ;
	b[x] += y;
	Up2 (x + lowbit(x), y);
}
int Down1 (int x) {
	if(x == 0)	return 0;
	return a[x] + Down1(x - lowbit(x));
}
int Down2 (int x) {
	if(x == 0)	return 0;
	return b[x] + Down2(x - lowbit(x));
}
signed main () {
	n = read(), m = read(), W = read();
	p[0] = 1;
	for(int i = 1; i <= 63; i ++)	p[i] = p[i - 1] << 1;
	int pro = 0, ans = 0;
	for(int i = 1; i <= n; i ++) {
		int x = read();
		Up1(i, x - pro);
		Up2(i, (x - pro) * (i - 1));
		pro = x; ans += x;
	}
	while(m --) {
		int L = read(), R = read(), d = read();
		Up1(L, d), Up1(R + 1, - d);
		Up2(L, (L - 1) * d), Up2(R + 1, R * - d);
		ans += (R - L + 1) * d;
		int w = W, l = 1, r = n;
		int tmp = check(w, ans), cnt = 0;
		while(l <= r) {
			int mid = (l + r) >> 1;
			if((Down1(mid) * mid - Down2(mid)) * p[tmp] < w)	cnt = mid, l = mid + 1;
			else	r = mid - 1;
		}
		write(tmp * n + cnt);
		putchar(10);
	}
	return 0;
}

TLE code:

#include <bits/stdc++.h>
#define int long long
#define lowbit(x) (x & (- x))
using namespace std;
const int N = 1e6 + 1;
int n, q, W, p[10010], sum[N], add[N], a[N];
int read () {
	int num = 0, fs = 1;
	char ch = getchar ();
	while ( ( ch < '0' || ch > '9' ) && ch != '-' )	ch = getchar ();
	if ( ch == '-' )	fs = - 1, ch = getchar ();
	while ( ch >= '0' && ch <= '9' ) num = num * 10 + ch - '0', ch = getchar();
	return num * fs;
}
int write(int x) {
	if(x < 0) {
		putchar('-');
		x = - x;
	}
	if(x < 10) {
		putchar(x + '0');
		return 0;
	}
	write(x / 10);
	putchar(x % 10 + '0');
}
int check(int &x, int y) {
	int ans = 0;
	while(x > y) {
		x = x - y;
		y = y * 2;
		ans ++;
	}
	return ans;
}
void Build(int l,int r,int rt){
	if(l==r){
		sum[rt]=a[l];
		return;
	}
	int mid=(l+r)>>1;
	Build(l,mid,rt*2);
	Build(mid+1,r,rt*2+1);
	sum[rt]=sum[rt*2]+sum[rt*2+1];
	return ;
}
void PushDown(int rt,int ls,int rs){
	if(add[rt]){
		add[rt*2]+=add[rt];
		add[rt*2+1]+=add[rt];
		sum[rt*2]+=add[rt]*ls;
		sum[rt*2+1]+=add[rt]*rs;
		add[rt]=0;		
	}
	return ;
}
int Query(int l,int r,int L,int R,int rt){
	if(l<=L&&R<=r)	return sum[rt];
	int mid=(L+R)>>1;
	PushDown(rt,mid-L+1,R-mid);
	if(r<=mid)	return Query(l,r,L,mid,rt*2);
	else if(l>=mid+1)	return Query(l,r,mid+1,R,rt*2+1);
	else	return Query(l,mid,L,mid,rt*2)+Query(mid+1,r,mid+1,R,rt*2+1);
}
void Update(int l,int r,int s,int L,int R,int rt){
	if(l<=L&&R<=r){
		sum[rt]+=(r-l+1)*s;
		add[rt]+=s;
		return ;
	}
	int mid=(L+R)>>1;
	PushDown(rt,mid-L+1,R-mid);
	if(r<=mid)	Update(l,r,s,L,mid,rt*2);
	else if(l>mid)	Update(l,r,s,mid+1,R,rt*2+1);
	else Update(l,mid,s,L,mid,rt*2),Update(mid+1,r,s,mid+1,R,rt*2+1);
	sum[rt]=sum[rt*2]+sum[rt*2+1];
	return ;
}
signed main () {
	n = read(), q = read(), W = read();
	int ans = 0;
	p[0] = 1;
	for(int i = 1; i <= 63; i ++)	p[i] = p[i - 1] << 1;
	for(int i = 1; i <= n; i ++)	a[i] = read(), ans += a[i];
	Build(1, n, 1);
	while (q --) {
		int L = read(), R = read(), d = read();
		Update (L, R, d, 1, n, 1); ans += d * (R - L + 1);
		int w = W;
		int tmp = check(w, ans);
		int l = 1, r = n, cnt = 0;
		while(l <= r) {
			int mid = (l + r) >> 1;
			if(w > Query(1, mid, 1, n, 1) * p[tmp])	cnt = mid, l = mid + 1;
			else	r = mid - 1;
		}
		write(tmp * n + cnt);
		putchar(10);
	}
	return 0;
}
2024/10/21 16:30
加载中...