Submission #781545


Source Code Expand

#include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)n;i++)
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define pb push_back
#define dbg(...) do{cerr<<__LINE__<<": ";dbgprint(#__VA_ARGS__, __VA_ARGS__);}while(0);

using namespace std;

namespace std{template<class S,class T>struct hash<pair<S,T>>{size_t operator()(const pair<S,T>&p)const{return ((size_t)1e9+7)*hash<S>()(p.first)+hash<T>()(p.second);}};template<class T>struct hash<vector<T>>{size_t operator()(const vector<T> &v)const{size_t h=0;for(auto i : v)h=h*((size_t)1e9+7)+hash<T>()(i)+1;return h;}};}
template<class T>ostream& operator<<(ostream &os, const vector<T> &v){os<<"[ ";rep(i,v.size())os<<v[i]<<(i==v.size()-1?" ]":", ");return os;}template<class T>ostream& operator<<(ostream &os,const set<T> &v){os<<"{ "; for(const auto &i:v)os<<i<<", ";return os<<"}";}
template<class T,class U>ostream& operator<<(ostream &os,const map<T,U> &v){os<<"{";for(const auto &i:v)os<<" "<<i.first<<": "<<i.second<<",";return os<<"}";}template<class T,class U>ostream& operator<<(ostream &os,const pair<T,U> &p){return os<<"("<<p.first<<", "<<p.second<<")";}
void dbgprint(const string &fmt){cerr<<endl;}template<class H,class... T>void dbgprint(const string &fmt,const H &h,const T&... r){cerr<<fmt.substr(0,fmt.find(","))<<"= "<<h<<" ";dbgprint(fmt.substr(fmt.find(",")+1),r...);}
typedef long long ll;typedef vector<int> vi;typedef pair<int,int> pi;const int inf = (int)1e9;const double INF = 1e12, EPS = 1e-9;

template<class T>struct SegTree{
	T *dat;
	int n;
	SegTree(int size = 1000000){
		for(n = 1; n < size; n *= 2);
		dat = new T[2 * n - 1];
		init();
	}
	~SegTree(){ delete [] dat; }
	
	void init(){
		rep(i, 2 * n - 1) dat[i] = inf;
	}
	void update(int k, T a){
		k += n - 1;
		dat[k] = a;
		
		while(k > 0){
			k = (k - 1) / 2;
			dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);
		}
	}
	T query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l) return inf;
		if(a <= l && r <= b) return dat[k];
		
		T vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
		T vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
		
		return min(vl, vr);
	}
	int leftmost(int a, int b, int v, int k, int l, int r){ //[a, i]で最小値がv未満になる最小のi
		if(r <= a || b <= l) return inf;
		if(l + 1 == r) return dat[k] < v ? l : inf;
		
		int m = (l + r) / 2;
		if(dat[k * 2 + 1] < v){
			int tmp = leftmost(a, b, v, k * 2 + 1, l, m);
			if(tmp < inf) return tmp;
		}
		return leftmost(a, b, v, k * 2 + 2, m, r);
	}
	int rightmost(int a, int b, int v, int k, int l, int r){ //[i, bで最小値がv未満になる最大のi
		if(r <= a || b <= l) return -inf;
		if(l + 1 == r) return dat[k] < v ? l : -inf;
		
		int m = (l + r) / 2;
		if(dat[k * 2 + 2] < v){
			int tmp = rightmost(a, b, v, k * 2 + 2, m, r);
			if(tmp > -inf) return tmp;
		}
		return rightmost(a, b, v, k * 2 + 1, l, m);
	}
	pi leftmost(int a, int b, int v){
		int idx = leftmost(a, b, v, 0, 0, n);
		return mp(idx, idx < inf ? dat[idx + n - 1] : 0);
	}
	pi rightmost(int a, int b, int v){
		int idx = rightmost(a, b, v, 0, 0, n);
		return mp(idx, idx > -inf ? dat[idx + n - 1] : 0);
	}
};




void size_rec(int, int);
void heavy_light_rec(int, int, int);

const int MX_L=17;
const int MX = 100010;

SegTree<int> *data[MX];
int bkt_sz;
int bkt_root[MX];

int n, q;
int val[MX];
int sz[MX];
int parent[MX_L][MX];
int depth[MX];
int which[MX];

vector<vi> e;

inline int lca(int a, int b){
	if(depth[a] > depth[b]) swap(a, b);
	int d = depth[b] - depth[a];
	rep(i, MX_L) if(d & 1 << i) b = parent[i][b];
	if(a == b) return a;
	for(int i = MX_L - 1; i >= 0; i--) if(parent[i][a] != parent[i][b]){
		a = parent[i][a];
		b = parent[i][b];
	}
	return parent[0][a];
}

inline void rec1(int &x, int s, int t){ //下から上に
	
	int w = which[s];
	if(w < 0) x %= val[s];
	else{
		int pos = depth[s] - depth[bkt_root[w]];
		int from = w == which[t] ? depth[t] - depth[bkt_root[w]] : 0;
		while(1){
			pi p = data[w]->rightmost(from, pos + 1, x + 1);
			if(p.first == -inf) break;
			x %= p.second;
			pos = p.first - 1;
		}
		if(w == which[t]) return;
	}
	if(s == t) return;
	
	if(w < 0) s = parent[0][s];
	else s = parent[0][bkt_root[w]];
	rec1(x, s, t);
}
inline void rec2(int &x, int s, int t){ //上から下に
	
	int w = which[s], ns = w < 0 ? parent[0][s] : parent[0][bkt_root[w]];
	if(s != t && (w < 0 || w != which[t])) rec2(x, ns, t);
	
	//dbg(x, s, t, w, ns);
	
	if(w < 0) x %= val[s];
	else{
		int pos = depth[s] - depth[bkt_root[w]];
		int from = w == which[t] ? depth[t] - depth[bkt_root[w]] : 0;
		while(1){
			pi p = data[w]->leftmost(from, pos + 1, x + 1);
			
			if(p.first == inf) break;
			x %= p.second;
			from = p.first + 1;
		}
	}
}
inline void solve(int &x, int s, int t){
	if(depth[s] >= depth[t]) rec1(x, s, t);
	else rec2(x, t, s);
}

int main(){
	scanf("%d%d", &n, &q);
	rep(i, n) scanf("%d", val + i);
	e.resize(n);
	
	rep(i, n - 1){
		int a, b; scanf("%d%d", &a, &b);
		a--; b--;
		e[a].pb(b);
		e[b].pb(a);
	}
	
	memset(which, -1, sizeof(which));
	size_rec(0, 0);
	heavy_light_rec(0, 0, -1);
	rep(i, MX_L - 1) rep(j, n) parent[i + 1][j] = parent[i][parent[i][j]];
	
	while(q--){
		int x, a, b; scanf("%d%d%d", &x, &a, &b); a--; b--;
		int c = lca(a, b);
		//dbg(a, b, c);
		solve(x, a, c);
		solve(x, c, b);
		printf("%d\n", x);
	}
	
	return 0;
}

void size_rec(int c, int p){
	sz[c] = 1;
	depth[c] = c == p ? 0 : depth[p] + 1;
	parent[0][c] = p;
	rep(i, e[c].size()) if(e[c][i] != p){
		size_rec(e[c][i], c);
		sz[c] += sz[e[c][i]];
	}
}
void heavy_light_rec(int c, int p, int root){
	
	bool found = 0;
	
	rep(i, e[c].size()){
		int to = e[c][i];
		if(to == p) continue;
		
		if(2 * sz[to] >= sz[c]){
			heavy_light_rec(to, c, root < 0 ? c : root);
			found = 1;
		}
		else heavy_light_rec(to, c, -1);
	}
	if(!found && root >= 0){
		/*
			各バケットの初期化処理
		*/
		int size = depth[c] - depth[root] + 1;
		bkt_root[bkt_sz] = root;
		data[bkt_sz] = new SegTree<int>(size);
		for(int v = c, i = size; ; v = parent[0][v]){
			which[v] = bkt_sz;
			data[bkt_sz]->update(--i, val[v]);
			if(v == root) break;
		}
		bkt_sz++;
	}
}

Submission Info

Submission Time
Task J - MODクエリ
User nadeko
Language C++11 (GCC 4.9.2)
Score 400
Code Size 6328 Byte
Status AC
Exec Time 391 ms
Memory 23624 KB

Compile Error

./Main.cpp: In function ‘int main()’:
./Main.cpp:160:23: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d%d", &n, &q);
                       ^
./Main.cpp:161:32: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
  rep(i, n) scanf("%d", val + i);
                                ^
./Main.cpp:165:34: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
   int a, b; scanf("%d%d", &a, &b);
                                  ^
./Main.cpp:177:43: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
   int x, a, b; scanf("%d%d%d", &x, &a, &b); a--; b--;
                                           ^

Judge Result

Set Name Small All
Score / Max Score 30 / 30 370 / 370
Status
AC × 16
AC × 38
Set Name Test Cases
Small 00_sample_path_01.txt, 15_path_00.txt, 15_path_01.txt, 15_path_02.txt, 15_path_03.txt, 15_path_04.txt, 16_path_05.txt, 16_path_06.txt, 16_path_07.txt, 16_path_08.txt, 16_path_09.txt, 17_path_10.txt, 17_path_11.txt, 17_path_12.txt, 17_path_13.txt, 17_path_14.txt
All 00_sample_path_01.txt, 15_path_00.txt, 15_path_01.txt, 15_path_02.txt, 15_path_03.txt, 15_path_04.txt, 16_path_05.txt, 16_path_06.txt, 16_path_07.txt, 16_path_08.txt, 16_path_09.txt, 17_path_10.txt, 17_path_11.txt, 17_path_12.txt, 17_path_13.txt, 17_path_14.txt, 20_random_15.txt, 20_random_16.txt, 20_random_17.txt, 21_random_18.txt, 21_random_19.txt, 21_random_20.txt, 30_random_21.txt, 30_random_22.txt, 30_random_23.txt, 40_random_24.txt, 40_random_25.txt, 40_random_26.txt, 49_sample_02.txt, 61_test_27.txt, 61_test_28.txt, 61_test_29.txt, 63_star_30.txt, 63_star_31.txt, 63_star_32.txt, 64_three_33.txt, 64_three_34.txt, 64_three_35.txt
Case Name Status Exec Time Memory
00_sample_path_01.txt AC 169 ms 1600 KB
15_path_00.txt AC 178 ms 1604 KB
15_path_01.txt AC 29 ms 1556 KB
15_path_02.txt AC 28 ms 1520 KB
15_path_03.txt AC 29 ms 1584 KB
15_path_04.txt AC 28 ms 1652 KB
16_path_05.txt AC 29 ms 1588 KB
16_path_06.txt AC 31 ms 1652 KB
16_path_07.txt AC 29 ms 1588 KB
16_path_08.txt AC 29 ms 1588 KB
16_path_09.txt AC 29 ms 1480 KB
17_path_10.txt AC 357 ms 23604 KB
17_path_11.txt AC 356 ms 23624 KB
17_path_12.txt AC 359 ms 23604 KB
17_path_13.txt AC 359 ms 23600 KB
17_path_14.txt AC 361 ms 23576 KB
20_random_15.txt AC 31 ms 1512 KB
20_random_16.txt AC 31 ms 1556 KB
20_random_17.txt AC 30 ms 1524 KB
21_random_18.txt AC 31 ms 1580 KB
21_random_19.txt AC 30 ms 1524 KB
21_random_20.txt AC 46 ms 1592 KB
30_random_21.txt AC 30 ms 1588 KB
30_random_22.txt AC 31 ms 1584 KB
30_random_23.txt AC 29 ms 1560 KB
40_random_24.txt AC 391 ms 16692 KB
40_random_25.txt AC 390 ms 16712 KB
40_random_26.txt AC 391 ms 16660 KB
49_sample_02.txt AC 30 ms 1500 KB
61_test_27.txt AC 322 ms 19772 KB
61_test_28.txt AC 314 ms 19844 KB
61_test_29.txt AC 332 ms 18324 KB
63_star_30.txt AC 245 ms 15120 KB
63_star_31.txt AC 247 ms 15156 KB
63_star_32.txt AC 244 ms 15120 KB
64_three_33.txt AC 382 ms 20444 KB
64_three_34.txt AC 381 ms 21440 KB
64_three_35.txt AC 391 ms 19892 KB