105862024-04-05 23:42:01CWMBarátokcpp17Accepted 100/100193ms33848 KiB
#include <iostream>
#include <optional>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;
#define int long long

struct fenwick_tree {
	vector<int> fwt;
	vector<int> base;
	fenwick_tree(vector<int>& input) {
		base = input;
		vector<int> prefixSum(input.size()+1);
		prefixSum[0] = 0;
		for (size_t i = 1; i < input.size()+1; i++)
		{
			prefixSum[i] = prefixSum[i - 1] + input[i-1];
		}
		fwt.push_back(prefixSum[0]);
		for (size_t i = 1; i < input.size()+1; i++)
		{
			int range = i - (i & (i - 1));
			fwt.push_back(prefixSum[i] - prefixSum[i - range]);
		}
	}
	int sumRange(int beg, int end) {
		end++;
		return sumFromBeginning(end) - sumFromBeginning(beg);
	}
	int sumFromBeginning(int end) {
		int sum = 0;
		while (end != 0) {
			sum += fwt[end];
			end = (end & (end - 1));
		}
		return sum;
	}
	void update(int idx, int newVal) {
		int dif = newVal - base[idx];
		base[idx] = newVal;
		idx++;
		while (idx < fwt.size()) {
			fwt[idx] += dif;
			int range = idx - (idx & (idx - 1));
			idx = (idx & (idx - 1)) + 2*range;
		}
	}
};

struct tNode {
	int val;
	int end;
	int beg;
	int par;
	tNode(int Val, int Beg, int End) {
		val = Val;
		beg = Beg;
		end = End;
		par = -1;
	}
	tNode() {};
};
struct slow_segment_tree {
	vector<tNode> smt;
	int fullSize = 1;
	slow_segment_tree(const vector<int>& inp) {
		for (size_t i = 0; i < 32; i++)
		{
			if (inp.size() > fullSize) fullSize *= 2;
			else break;
		}
		smt.resize(2 * fullSize - 1);
		for (size_t i = 0; i < inp.size(); i++)
		{
			smt[i] = tNode(inp[i],i,i);
		}
		int cur = 0;
		for (size_t i = fullSize; i < smt.size(); i++)
		{
			smt[i] = tNode(smt[cur].val + smt[cur + 1].val, smt[cur].beg, smt[cur + 1].end);
			smt[cur].par = i;
			smt[cur+1].par = i;
			cur += 2;
		}
	}
	int sumRange(int beg, int end) {
		int ans = 0;
		int cur = beg;
		while (true)
		{
			if (smt[cur].end==end) {
				ans += smt[cur].val;
				break;
			}
			tNode par = smt[smt[cur].par];
			if (par.beg >= cur && par.end <= end) {
				cur = smt[cur].par;
			}
			else {
				ans += smt[cur].val;
				cur = smt[cur].end + 1;
			}
		}
		return ans;
	}
	void update(int index, int value) {
		int cur = index;
		int dif = value - smt[cur].val;
		while (cur!=-1)
		{
			smt[cur].val += dif;
			cur = smt[cur].par;
		}
	}
};

struct segment_tree {
	vector<int> graph;
	void construct(vector<int>& prefixSum, int l, int r, int graphIdx) {
		if (r <= l) return;
		int val = prefixSum[r] - prefixSum[l];
		graph[graphIdx] = val;
		if (l >= r - 1) return;
		construct(prefixSum, l, (r+l) / 2, graphIdx*2);
		construct(prefixSum, (r+l)/2, r, graphIdx * 2 + 1);
	}
	segment_tree(vector<int> input) {
		graph.resize(4*input.size());
		vector<int> prefixSum(input.size() + 1);
		prefixSum[0] = 0;
		for (size_t i = 1; i < input.size() + 1; i++)
		{
			prefixSum[i] = prefixSum[i - 1] + input[i - 1];
		}
		construct(prefixSum, 0, input.size(), 1);
	}
	void sR(int beg, int end, int idx, int cB, int cE, int& ans) {
		int c1B = cB;
		int c1E = (cB + cE) / 2;
		int c2B = c1E;
		int c2E = cE;
		if (c1E > beg) {
			if (c1B >= beg && c1E <= end) {
				ans += graph[idx*2];
			}
			else {
				sR(beg, end, idx * 2, c1B, c1E, ans);
			}
		}
		if (end > c2B) {
			if (c2E <= end && c2B >= beg) {
				ans += graph[idx*2+1];
			}
			else {
				sR(beg, end, idx * 2 + 1, c2B, c2E, ans);
			}
		}
	}
	int sumRange(int beg, int end) {
		int cB = 0;
		int cE = graph.size() / 4;
		int ans = 0;
		sR(beg, end+1, 1, cB, cE, ans);
		return ans;
	}
	void u(int cBeg, int cEnd, int index, int cIdx, int value) {
		if (cBeg == cEnd-1) {
			graph[cIdx] = value;
			return;
		}
		int bp = (cBeg + cEnd) / 2;
		if (index < bp) {
			u(cBeg, bp, index, cIdx*2, value);
		}
		else {
			u(bp, cEnd, index, cIdx * 2 + 1, value);
		}
		graph[cIdx] = graph[cIdx * 2] + graph[cIdx * 2 + 1];
	}
	void update(int index, int value) {
		u(0, graph.size() / 4, index, 1, value);
	}
};

signed main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	/*int n, q;
	cin >> n >> q;
	vector<int> inp(n);
	for (size_t i = 0; i < n; i++)
	{
		cin >> inp[i];
	}
	segment_tree sm = segment_tree(inp);
	for (size_t i = 0; i < q; i++)
	{
		int a, b, c;
		cin >> a >> b >> c;
		if (a == 1) {
			sm.update(b, c);
		}
		else {
			c--;
			cout << sm.sumRange(b, c) << "\n";
		}
	}*/
	/*vector<int> tst{ 0,1,2,3,4,5,6,7,8,9,10 };
	segment_tree st = segment_tree(tst);
	st.update(3, 1000);
	cout << st.sumRange(1, 5);*/
	int n;
	cin >> n;
	vector<int> inp(n, 1);
	vector<pair<int, int>> sVec(n);
	for (size_t i = 0; i < n; i++)
	{
		int a;
		cin >> a;
		sVec[i] = { a,i };
	}
	sort(sVec.begin(), sVec.end());
	segment_tree st = segment_tree(inp);
	int ans = 0;
	for (size_t i = 0; i < n; i++)
	{
		st.update(sVec[i].second, 0);
		int beg = max(0ll, sVec[i].second - sVec[i].first);
		int end = min(n - 1, sVec[i].second + sVec[i].first);
		ans += st.sumRange(beg, end);
	}
	cout << ans << "\n";
	return 0;
}
SubtaskSumTestVerdictTimeMemory
subtask10/0
1Accepted3ms1888 KiB
2Accepted90ms20068 KiB
subtask211/11
3Accepted3ms2940 KiB
4Accepted4ms3852 KiB
5Accepted6ms3856 KiB
6Accepted4ms4020 KiB
7Accepted6ms4108 KiB
8Accepted4ms4252 KiB
9Accepted4ms4252 KiB
10Accepted4ms4400 KiB
subtask312/12
11Accepted168ms32192 KiB
12Accepted156ms32540 KiB
13Accepted167ms32404 KiB
14Accepted100ms32572 KiB
15Accepted156ms33032 KiB
16Accepted97ms32692 KiB
17Accepted129ms32760 KiB
subtask431/31
18Accepted137ms32824 KiB
19Accepted152ms33076 KiB
20Accepted93ms33076 KiB
21Accepted135ms33076 KiB
22Accepted146ms33272 KiB
23Accepted162ms33216 KiB
24Accepted119ms33100 KiB
25Accepted174ms33164 KiB
26Accepted111ms33164 KiB
subtask546/46
27Accepted173ms33488 KiB
28Accepted186ms33368 KiB
29Accepted193ms33688 KiB
30Accepted108ms33752 KiB
31Accepted171ms33752 KiB
32Accepted93ms33644 KiB
33Accepted108ms33640 KiB
34Accepted107ms33640 KiB
35Accepted150ms33636 KiB
36Accepted93ms33700 KiB
37Accepted143ms33640 KiB
38Accepted177ms33640 KiB
39Accepted170ms33848 KiB
40Accepted123ms33728 KiB
41Accepted178ms33636 KiB