QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#96954 | #2918. Tree Number Generator | megz112233 | TL | 5ms | 12792kb | C++20 | 4.3kb | 2023-04-16 09:04:06 | 2023-04-16 09:04:08 |
Judging History
answer
#include <bits/stdc++.h>
#define ll long long
#define all(v) v.begin(),v.end()
#define sz(x) (int) (x).size()
#define el '\n'
#define Megz ios::sync_with_stdio(0);cin.tie(0);ios_base::sync_with_stdio(0);
using namespace std;
int mod = 1e9 + 7, N = 1e6+5;
ll binpow (ll x , ll y ){
ll res = 1 ;
while (y){
if (y%2)res= ((res)%mod * (x)%mod) %mod ;
x=((x)%mod*(x)%mod)%mod ;
y/=2 ;
}
return res%mod ;
}
ll mul (ll x , ll y ){
x%=mod ;
y%=mod ;
return 1ll* (x*y)%mod;
}
ll plu (ll x , ll y ){
x%=mod ;
y%=mod ;
return 1ll* (x+y)%mod;
}
struct vertex {
ll anc , up , down ;
};
struct lca {
vector<vector<vertex>> yup_lifting ;
vector<ll> depth ;
vector<ll> adj[400005] ;
vector<ll> val ;
vector<ll> pow ;
const int LOG = 20 ;
int get_down (int x) {
string s = to_string(x) ;
reverse(all(s)) ;
x = stoi(s) ;
return x ;
}
void init (int n ){
depth.assign(n+5, 0) ;
val.assign(n+5,0) ;
yup_lifting.assign(n+5, vector<vertex>(LOG, {0,0,0})) ;
for (int i =0 ; i< LOG ; i++){
pow.push_back(binpow(10,(1<<i))) ;
}
}
void dfs (int node , int par ){
yup_lifting[1][0] = {par, val[1], val[1]};
for (auto child : adj[node]){
if (child == par)continue;
depth[child] = depth[node]+1 ;
yup_lifting[child][0] = {node, val[child], val[child]};
for (int i =1 ; i < LOG ;i++){
yup_lifting[child][i].anc = yup_lifting[yup_lifting[child][i-1].anc][i-1].anc ;
yup_lifting[child][i].up = plu(mul (yup_lifting[child][i-1].up , pow[i-1]) , yup_lifting[yup_lifting[child][i-1].anc][i-1].up ) ;
yup_lifting[child][i].down = plu(mul (yup_lifting[yup_lifting[child][i-1].anc][i-1].down , pow[i-1]) , yup_lifting[child][i-1].down) ;
}
dfs(child, node) ;
}
}
vertex go_up (int k , int node ){
vertex curr = {node , 0,0} ;
int cnt = 0 ;
for (int i =0 ; i < LOG ; i++){
if (k&(1<<i)){
curr.up = plu(mul(curr.up , pow[i]) , yup_lifting[curr.anc][i].up) ;
curr.down = plu(mul (yup_lifting[curr.anc][i].down , binpow(10,cnt)) , curr.down) ;
cnt+=(1<<i) ;
curr.anc = yup_lifting[curr.anc][i].anc ;
}
}
return curr ;
}
int get_lca (int a , int b){
if (depth[a]<depth[b])swap(a,b) ;
int k = depth[a]-depth[b] ;
a = go_up(k , a).anc ;
if (a==b){
return a ;
}
for (int i = LOG -1 ; i>=0 ; i--){
if (yup_lifting[a][i].anc!=yup_lifting[b][i].anc){
a = go_up((1<<i) , a) .anc;
b = go_up((1<<i) , b).anc ;
}
}
return go_up(1,a).anc ;
}
int get_query (int from ,int to){
int lca = get_lca(from , to ) ;
if (lca==from){
vertex ans = go_up(depth[to]-depth[from]+1 , to) ;
return ans.down ;
}
else if (lca==to){
vertex ans = go_up(depth[from]-depth[to]+1 , from) ;
return ans.up ;
}
else {
int left = go_up(depth[from]-depth[lca]+1 , from).up , right = go_up((depth[to]-depth[lca]) , to).down ;
return plu(mul(left , binpow(10, depth[lca]-depth[to]) ), right) ;
}
}
} lca;
void acc() {
int n , q ;cin >>n>>mod >>q ;
lca.init(n+5) ;
for (int i =0 ; i < n-1; i++){
int x , y ;cin>>x>>y ;
x%=mod ;
y%=mod ;
lca.adj[x].push_back(y) ;
lca.adj[y].push_back(x) ;
}
for (int i =1 ; i<=n ; i++){
cin >>lca.val[i] ;
}
lca.dfs(1, 0) ;
lca.go_up(5,3) ;
while (q--){
int from , to ;cin >>from >>to ;
cout <<lca.get_query(from ,to)<<el ;
}
}
int main() {
Megz
int t = 1;
while (t--) {
acc();
}
}
//5 100 4
//1 2
//1 3
//1 4
//5 3
//1
//2
//3
//0
//4
//1 5
//5 1
//4 2
//3 3
详细
Test #1:
score: 100
Accepted
time: 2ms
memory: 12792kb
input:
2 1 4 1 2 1 3 1 2 2 1 1 1 2 2
output:
0 0 0 0
result:
ok 4 lines
Test #2:
score: 0
Accepted
time: 5ms
memory: 12756kb
input:
3 10 5 1 2 2 3 0 0 0 1 3 3 1 2 2 2 3 2 1
output:
0 0 0 0 0
result:
ok 5 lines
Test #3:
score: -100
Time Limit Exceeded
input:
2000 2 2000 937 1471 1672 937 356 1672 976 356 1257 356 1503 1257 783 1503 1783 937 1284 976 1955 1503 802 1257 583 1471 526 356 701 1783 393 1955 307 1955 386 1955 1070 937 1724 802 1397 1724 1140 937 422 526 1941 1955 1638 937 1469 526 1800 526 1035 1800 1009 1140 1195 1800 142 1471 1225 1469 1524...