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
2016-06-26 18:13:29+0900
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
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