D. Time to Raid Cowavans(按数据分块

题意:3e5个数,3e5组询问,每组询问给(a,b)—— 问从a,a+b,a+2b,。。。一直到下标超过n为止所有下标的和是多少

【链接】Problem - D - Codeforces

分析:还是很妙的很优雅的分块 —— 首先这个暴力肯定不行,想想怎么优化,发现如果存在相同的b,那么可以做一个后缀和优化,但是如果他全都不一样,这种极端情况也是可以卡成n2的,—— 但发现数据大的时候其实直接做即可,这里就要取一个优雅的平衡点 —— \sqrt n,大于根号的直接暴力,小于的用前缀和处理,复杂度最大是n\sqrt n

【离线版】

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 15;
const int mo = 998244353;
#define pb push_back
#define pii pair<int,int>
#define ft first
#define sd second
#define ffor(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define For(i,a,b,c) for(int i=(a);i<=(b);i+=(c))
#define rfor(i,a,b,c) for(int i=(a);i>(b);i-=(c))
#define Rfor(i,a,b,c) for(int i=(a);i>=(b);i-=(c))
#define all(x) (x).begin(), (x).end()
#define debug1(x) cerr<<"! "<<x<<endl;
#define debug2(x,y) cerr<<"#  "<<x<<" "<<y<<endl;
class Partition
{
public:
	Partition(int _n) : n(_n) {
		v.resize(n + 1);
		for (int i = 1; i <= n; i++) {
			cin >> v[i];
		}
		blo = sqrt(n);
		pr.resize(blo + 1);
	}

	void init() {
		sort(q.begin(), q.end());
		int lst = -1;
		for (auto x : q) {
			int i = x.ft.ft;
			if (i > blo) {
				ll res = 0;
				for (int j = x.ft.sd; j <= n; j += i) {
					res += v[j];
				}
				ans[x.sd] = res;
				continue;
			}
			if (i == lst) {
				ans[x.sd] = pr[x.ft.sd];
				continue;
			}
			pr.clear();
			pr.resize(n + 1);
			for (int j = n; j >= 1; j--) {
				if (j + i <= n) {
					pr[j] += pr[j + i] + v[j];
				} else {
					pr[j] += v[j];
				}
			}
			ans[x.sd] = pr[x.ft.sd];
			lst = i;
		}
	}

	void GetQ() {
		int m; cin >> m; ans.resize(m + 1);
		for (int i = 1; i <= m; i++) {
			int a, b; cin >> a >> b;
			q.pb({{b, a}, i});
		}
		init();
		for (int i = 1; i <= m; i++) {
			cout << ans[i] << '\n';
		}
	}

private:
	vector<int> v; vector<pair<pii, int>> q;
	vector<ll> pr, ans;
	int n, blo;
};
void slv() {
	int n; cin >> n;
	Partition Pt(n);
	Pt.GetQ();
}
int main() {
	ios::sync_with_stdio(false); cin.tie(0);
	slv();
}

【在线版】

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+15;
const int mo = 998244353;
#define pb push_back
#define pii pair<int,int>
#define ft first
#define sd second
#define ffor(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define For(i,a,b,c) for(int i=(a);i<=(b);i+=(c))
#define rfor(i,a,b,c) for(int i=(a);i>(b);i-=(c))
#define Rfor(i,a,b,c) for(int i=(a);i>=(b);i-=(c))
#define all(x) (x).begin(), (x).end()
#define debug1(x) cerr<<"! "<<x<<endl;
#define debug2(x,y) cerr<<"#  "<<x<<" "<<y<<endl;
class Partition
{
public:
	Partition(int _n) : n(_n) {
		v.resize(n + 1);
		for(int i = 1; i <= n; i++) {
			cin >> v[i];
		}
		blo = sqrt(n); 
		pr.resize(blo + 1);
		for(int i = 1; i <= blo ;i ++) {
			pr[i].resize(n + 1);
			for(int j = n; j >= 1; j--) {
				if(j + i <= n) {
					pr[i][j] += pr[i][j + i] + v[j];
				} else {
					pr[i][j] += v[j];
				}
			}
		}
	}

	ll query(int a, int b) {
		if(b > blo) {
			ll ans = 0;
			for(int i = a; i <= n; i+=b) {
				ans += v[i];
			}
			return ans;
		} else {
			return pr[b][a];
		}
	}

private:
	vector<int> v;
	vector<vector<ll>> pr;
	int n, blo;
};
void slv(){
	int n; cin >> n;
	Partition Pt(n);
	int m; cin >> m;
	for(int i = 1; i <= m; i++) {
		int a, b; cin >> a >> b;
		cout << Pt.query(a, b) << '\n';
	}
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	slv();
}

PS:自从换成C++的写法突然感觉之前函数的写法有点丑hh

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值