代码的复杂度不对吗
查看原帖
代码的复杂度不对吗
999274
CNS_5t0_0r2楼主2024/7/30 12:53

第一次写值域分块,然后 TLE 56分,感觉不像是常数的问题,又不像是复杂度的问题。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 9,M = 1e5 + 9,SqrtN = 359;
int n,m;
int a[N],max_a; 
struct Block{
	struct block{
		int l,r;
		int val1,val2;
		//val1:该值域内有多少个数(可重复) 
		//val2:该值域内有多少个数(不重复) 
	} b[SqrtN];
	int block_len,block_cnt;
	int belong[N];
	void build_block(int len){
		block_len = block_cnt = sqrt(len);
		for(int i = 1;i <= block_cnt;i++){
			b[i].l = b[i - 1].r + 1;
			b[i].r = b[i].l + block_len - 1; 
		}
	}
} block1,block2;//block1:数列分块,block2:值域分块 
struct Query{
	int l,r,x,y;
	int id;
} q[M];
int ans1[M],ans2[M];
bool cmp(Query q1,Query q2){
	return (block1.belong[q1.l] ^ block1.belong[q1.l]) ? block1.belong[q1.l] < block1.belong[q1.l] : q1.r < q2.r;
}

int cnt[N];
void update(int v,int k){
	cnt[v] += k;
	block2.b[block2.belong[v]].val1 += k;
	block2.b[block2.belong[v]].val2 += ((k == 1 && cnt[v] == 1) || (k == -1 && cnt[v] == 0)) * k;
}

int query1(int l,int r){
	int pos_l = block2.belong[l],pos_r = block2.belong[l];
	int ret = 0;
	if(pos_l == pos_r){
		for(int i = l;i <= r;i++)
			ret += cnt[i];
		return ret;
	}
	for(int i = l;i <= block2.b[pos_l].r;i++)
		ret += cnt[i];
	for(int i = block2.b[pos_r].l;i <= r;i++)
		ret += cnt[i];
	for(int i = pos_l + 1;i <= pos_r - 1;i++)
		ret += block2.b[i].val1;
	return ret;
}
int query2(int l,int r){
	int pos_l = block2.belong[l],pos_r = block2.belong[l];
	int ret = 0;
	if(pos_l == pos_r){
		for(int i = l;i <= r;i++)
			ret += (cnt[i] >= 1);
		return ret;
	}
	for(int i = l;i <= block2.b[pos_l].r;i++)
		ret += (cnt[i] >= 1);
	for(int i = block2.b[pos_r].l;i <= r;i++)
		ret += (cnt[i] >= 1);
	for(int i = pos_l + 1;i <= pos_r - 1;i++)
		ret += block2.b[i].val2;
	return ret;
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin >> n >> m;
	block1.build_block(n);
	for(int i = 1;i <= n;i++){
		cin >> a[i];
		max_a = max(max_a,a[i]);
	}
	block2.build_block(max_a);
	for(int i = 1;i <= m;i++){
		cin >> q[i].l >> q[i].r >> q[i].x >> q[i].y;
		q[i].id = i;
	}
	sort(q + 1,q + m + 1,cmp);
	int lres = 1,rres = 0,tmp = 0;
    for(int i = 1;i <= m;i++){
        int L = q[i].l,R = q[i].r;
        int x = q[i].x,y = q[i].y;
        while(lres > L)
        	update(a[--lres],1);
        while(rres < R)
        	update(a[++rres],1);
        while(lres < L)
        	update(a[lres++],-1);
        while(rres > R)
        	update(a[rres--],-1);
        ans1[q[i].id] = query1(x,y);
        ans2[q[i].id] = query2(x,y);
    }
    for(int i = 1;i <= m;i++)
    	cout << ans1[i] << ' ' << ans2[i] << '\n';
	return 0;
}
2024/7/30 12:53
加载中...