답안 #36535

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
36535 2017-12-10T10:12:13 Z szawinis Garaža (COCI17_garaza) C++14
120 / 160
1366 ms 36464 KB
#include <bits/stdc++.h>
#define fs first
#define sc second
using namespace std;
using ll = long long;
const int N = 1 << 17;

int n, q, a[N], lb[2*N], rb[2*N]; // lb, rb = left bound, right bound for each segment
ll t[2*N];
vector<pair<int,int> > pref[2*N], suff[2*N];

void build(int pos, int l, int r) {
	lb[pos] = l; rb[pos] = r;
	if(l == r) {
		pref[pos] = suff[pos] = {{a[l], l}};
		t[pos] = a[l] > 1;
		return;
	}
	int mid = l+r >> 1;
	build(pos<<1, l, mid);
	build(pos<<1|1, mid+1, r);
	// init t
	t[pos] = t[pos<<1] + t[pos<<1|1];
	for(int i = 0, j = suff[pos<<1].size()-1; i < pref[pos<<1|1].size(); i++) {
		while(j >= 0 && __gcd(suff[pos<<1][j].fs, pref[pos<<1|1][i].fs) == 1) --j;
		if(j < 0) continue;
		ll res = mid - (j < suff[pos<<1].size()-1 ? suff[pos<<1][j+1].sc : l-1);
		res *= (i < pref[pos<<1|1].size()-1 ? pref[pos<<1|1][i+1].sc : r+1) - pref[pos<<1|1][i].sc;
		t[pos] += res;
	}
	// init pref
	pref[pos] = pref[pos<<1];
	for(int i = 0; i < pref[pos<<1|1].size(); i++) {
		int new_gcd = __gcd(pref[pos<<1|1][i].fs, pref[pos<<1].back().fs);
		if(new_gcd != pref[pos].back().fs)
			pref[pos].emplace_back(new_gcd, pref[pos<<1|1][i].sc);
	}
	// init suff
	suff[pos] = suff[pos<<1|1];
	for(int i = 0; i < suff[pos<<1].size(); i++) {
		int new_gcd = __gcd(suff[pos<<1][i].fs, suff[pos<<1|1].back().fs);
		if(new_gcd != suff[pos].back().fs)
			suff[pos].emplace_back(new_gcd, suff[pos<<1][i].sc);
	}
}

void update(int pos, int l, int r, int idx, int v) {
	if(l == r) {
		pref[pos] = suff[pos] = {{v, l}};
		t[pos] = v > 1;
		return;
	}
	int mid = l+r >> 1;
	if(idx <= mid) update(pos<<1, l, mid, idx, v);
	else update(pos<<1|1, mid+1, r, idx, v);
	// update t
	t[pos] = t[pos<<1] + t[pos<<1|1];
	for(int i = 0, j = suff[pos<<1].size()-1; i < pref[pos<<1|1].size(); i++) {
		while(j >= 0 && __gcd(suff[pos<<1][j].fs, pref[pos<<1|1][i].fs) == 1) --j;
		if(j < 0) continue;
		ll res = mid - (j < suff[pos<<1].size()-1 ? suff[pos<<1][j+1].sc : l-1);
		res *= (i < pref[pos<<1|1].size()-1 ? pref[pos<<1|1][i+1].sc : r+1) - pref[pos<<1|1][i].sc;
		t[pos] += res;
	}
	// update pref
	pref[pos] = pref[pos<<1];
	for(int i = 0; i < pref[pos<<1|1].size(); i++) {
		int new_gcd = __gcd(pref[pos<<1|1][i].fs, pref[pos<<1].back().fs);
		if(new_gcd != pref[pos].back().fs)
			pref[pos].emplace_back(new_gcd, pref[pos<<1|1][i].sc);
	}
	// update suff
	suff[pos] = suff[pos<<1|1];
	for(int i = 0; i < suff[pos<<1].size(); i++) {
		int new_gcd = __gcd(suff[pos<<1][i].fs, suff[pos<<1|1].back().fs);
		if(new_gcd != suff[pos].back().fs)
			suff[pos].emplace_back(new_gcd, suff[pos<<1][i].sc);
	}
}

ll query(int l, int r) {
	int tmpl = l, tmpr = r;
	ll ret = 0;
	vector<int> segs;
	for(l += N, r += N+1; l < r; l >>= 1, r >>= 1) {
		if(l & 1) {
			ret += t[l];
			segs.push_back(l);
			++l;
		}
		if(r & 1) {
			--r;
			ret += t[r];
			segs.push_back(r);
		}
	}
	l = tmpl, r = tmpr;
	sort(segs.begin(), segs.end(), [] (int i, int j) { return lb[i] < lb[j]; });
	vector<pair<int,int> > loc_suff;
	for(int pos: segs) {
		for(int i = 0, j = loc_suff.size()-1; i < pref[pos].size(); i++) {
			while(j >= 0 && __gcd(loc_suff[j].fs, pref[pos][i].fs) == 1) --j;
			if(j < 0) continue;
			ll res = lb[pos]-1 - (j < loc_suff.size()-1 ? loc_suff[j+1].sc : l-1);
			res *= (i < pref[pos].size()-1 ? pref[pos][i+1].sc : rb[pos]+1) - pref[pos][i].sc;
			ret += res;
		}
		vector<pair<int,int> > tmp = suff[pos];
		for(int i = 0; i < loc_suff.size(); i++) {
			int new_gcd = __gcd(loc_suff[i].fs, suff[pos].back().fs);
			if(new_gcd != tmp.back().fs)
				tmp.emplace_back(new_gcd, loc_suff[i].sc);
		}
		loc_suff = tmp;
	}
	return ret;
}

int main() {
	scanf("%d %d", &n, &q);
	fill(a, a+N, 1);
	for(int i = 0; i < n; i++) scanf("%d", a+i);
	build(1, 0, N-1);
	while(q--) {
		int type; cin >> type;
		if(type == 1) {
			int idx, v; scanf("%d %d", &idx, &v); --idx;
			update(1, 0, N-1, idx, v);
		} else {
			int l, r; scanf("%d %d", &l, &r); --l; --r;
			printf("%lld\n", query(l, r));
		}
	}
}

Compilation message

garaza.cpp: In function 'void build(int, int, int)':
garaza.cpp:19:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  int mid = l+r >> 1;
             ^
garaza.cpp:24:46: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i = 0, j = suff[pos<<1].size()-1; i < pref[pos<<1|1].size(); i++) {
                                              ^
garaza.cpp:27:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   ll res = mid - (j < suff[pos<<1].size()-1 ? suff[pos<<1][j+1].sc : l-1);
                     ^
garaza.cpp:28:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   res *= (i < pref[pos<<1|1].size()-1 ? pref[pos<<1|1][i+1].sc : r+1) - pref[pos<<1|1][i].sc;
             ^
garaza.cpp:33:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i = 0; i < pref[pos<<1|1].size(); i++) {
                   ^
garaza.cpp:40:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i = 0; i < suff[pos<<1].size(); i++) {
                   ^
garaza.cpp: In function 'void update(int, int, int, int, int)':
garaza.cpp:53:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  int mid = l+r >> 1;
             ^
garaza.cpp:58:46: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i = 0, j = suff[pos<<1].size()-1; i < pref[pos<<1|1].size(); i++) {
                                              ^
garaza.cpp:61:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   ll res = mid - (j < suff[pos<<1].size()-1 ? suff[pos<<1][j+1].sc : l-1);
                     ^
garaza.cpp:62:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   res *= (i < pref[pos<<1|1].size()-1 ? pref[pos<<1|1][i+1].sc : r+1) - pref[pos<<1|1][i].sc;
             ^
garaza.cpp:67:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i = 0; i < pref[pos<<1|1].size(); i++) {
                   ^
garaza.cpp:74:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i = 0; i < suff[pos<<1].size(); i++) {
                   ^
garaza.cpp: In function 'll query(int, int)':
garaza.cpp:101:43: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int i = 0, j = loc_suff.size()-1; i < pref[pos].size(); i++) {
                                           ^
garaza.cpp:104:28: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    ll res = lb[pos]-1 - (j < loc_suff.size()-1 ? loc_suff[j+1].sc : l-1);
                            ^
garaza.cpp:105:14: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    res *= (i < pref[pos].size()-1 ? pref[pos][i+1].sc : rb[pos]+1) - pref[pos][i].sc;
              ^
garaza.cpp:109:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int i = 0; i < loc_suff.size(); i++) {
                    ^
garaza.cpp: In function 'int main()':
garaza.cpp:120:24: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d %d", &n, &q);
                        ^
garaza.cpp:122:45: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  for(int i = 0; i < n; i++) scanf("%d", a+i);
                                             ^
garaza.cpp:127:40: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
    int idx, v; scanf("%d %d", &idx, &v); --idx;
                                        ^
garaza.cpp:130:36: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
    int l, r; scanf("%d %d", &l, &r); --l; --r;
                                    ^
# 결과 실행 시간 메모리 Grader output
1 Correct 96 ms 35288 KB Output is correct
2 Correct 129 ms 35420 KB Output is correct
3 Correct 129 ms 35420 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 263 ms 35940 KB Output is correct
2 Correct 396 ms 35816 KB Output is correct
3 Correct 489 ms 35552 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 776 ms 36464 KB Output is correct
2 Correct 1366 ms 36196 KB Output is correct
3 Correct 1036 ms 35812 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Runtime error 0 ms 0 KB -1: Interrupted system call
2 Halted 0 ms 0 KB -