QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#97527#2918. Tree Number Generatormegz112233TL 18ms17536kbC++234.2kb2023-04-17 05:31:242023-04-17 05:31:25

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-04-17 05:31:25]
  • 评测
  • 测评结果:TL
  • 用时:18ms
  • 内存:17536kb
  • [2023-04-17 05:31:24]
  • 提交

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;
int mul  (int x , int y ){
    x%=mod  ;
    y%=mod  ;
    return 1ll* (x*y)%mod;
}
int plu  (int x , int y ){
    x%=mod  ;
    y%=mod  ;
    return 1ll* (x+y)%mod;
}
struct vertex {
    int anc ,  up  ,  down   ;
};
struct lca {
    vector<vector<vertex>>  yup_lifting ;
    vector<int> depth   ;
    vector<int> adj[400005] ;
    vector<int> val  ;
    vector<int> pow  ;
    const  int   LOG  =  19 ;
    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})) ;
        pow.push_back(1) ;
        for (int i =0 ;  i<= (1<<19) ; i++){
            pow.push_back(mul(pow.back(),10)) ;
        }
    }
    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[(1<<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[(1<<i-1)]) , yup_lifting[child][i-1].down)  ;
            }

            dfs(child, node) ;
        }
    }
    vertex go_up (int k  ,  int  node  ){
        vertex curr =  {node , 0,0} ;
        ll cnt = 0 ;
        for (int i =0 ; i < LOG  ; i++){
            if (k&(1<<i)){
                curr.up = plu(mul(curr.up , pow[(1<<i)]) , yup_lifting[curr.anc][i].up) ;
                curr.down = plu(mul  (yup_lifting[curr.anc][i].down , pow[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 = yup_lifting[a][i].anc;
                b = yup_lifting[b][i].anc ;
            }
        }
        return yup_lifting[a][0].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 ;
           // cout <<left <<" " <<right<<" "<<depth[lca]<<" " <<depth[to]<<" "  <<lca  <<el ;
            return plu(mul(left , pow[( depth[to]-depth[lca])] ),  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) ;
    //cout <<lca.get_lca(4,2) <<"hahaahah"<< el ;
    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: 18ms
memory: 16864kb

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: 11ms
memory: 17536kb

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...

output:


result: