• [BJOI2018]求和


    题目大意:
      一个$n(nle3 imes10^5)$个结点的有根树。$m(mle3 imes10^5)$次询问,每次询问$x,y$路径上所有结点深度$k(kle50)$次方和。

    思路:
      树上前缀和+LCA即可。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<algorithm>
     4 #include<sys/mman.h>
     5 #include<sys/stat.h>
     6 typedef long long int64;
     7 class MMapInput {
     8     private:
     9         char *buf,*p;
    10         int size;
    11     public:
    12         MMapInput() {
    13             register int fd=fileno(stdin);
    14             struct stat sb;
    15             fstat(fd,&sb);
    16             size=sb.st_size;
    17             buf=reinterpret_cast<char*>(mmap(0,size,PROT_READ,MAP_PRIVATE,fileno(stdin),0));
    18             p=buf;
    19         }
    20         char getchar() {
    21             return (p==buf+size||*p==EOF)?EOF:*p++;
    22         }
    23 };
    24 MMapInput mmi;
    25 inline int getint() {
    26     register char ch;
    27     while(!isdigit(ch=mmi.getchar()));
    28     register int x=ch^'0';
    29     while(isdigit(ch=mmi.getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    30     return x;
    31 }
    32 const int N=3e5+1,logN=19,K=51,mod=998244353;
    33 int h[N];
    34 struct Edge {
    35     int to,next;
    36 };
    37 Edge e[N<<1];
    38 inline void add_edge(const int &u,const int &v) {
    39     e[++h[0]]=(Edge){v,h[u]};h[u]=h[0];
    40     e[++h[0]]=(Edge){u,h[v]};h[v]=h[0];
    41 }
    42 int dep[N]={-1},anc[N][logN],sum[N][K];
    43 inline int log2(const float &x) {
    44     return ((unsigned&)x>>23&255)-127;
    45 }
    46 void dfs(const int &x,const int &par) {
    47     dep[x]=dep[anc[x][0]=par]+1;
    48     for(register int i=1,v=dep[x];i<K;i++) {
    49         sum[x][i]=(sum[par][i]+v)%mod;
    50         v=(int64)v*dep[x]%mod;
    51     }
    52     for(register int i=1;i<=log2(dep[x]);i++) {
    53         anc[x][i]=anc[anc[x][i-1]][i-1];
    54     }
    55     for(int i=h[x];i;i=e[i].next) {
    56         const int &y=e[i].to;
    57         if(y==par) continue;
    58         dfs(y,x);
    59     }
    60 }
    61 inline int lca(int x,int y) {
    62     if(dep[x]!=dep[y]) {
    63         if(dep[x]<dep[y]) std::swap(x,y);
    64         for(register int i=log2(dep[x]-dep[y]);~i;i--) {
    65             if(dep[anc[x][i]]>=dep[y]) x=anc[x][i];
    66         }
    67     }
    68     if(x==y) return x;
    69     for(register int i=log2(dep[x]);~i;i--) {
    70         if(anc[x][i]!=anc[y][i]) {
    71             x=anc[x][i];
    72             y=anc[y][i];
    73         }
    74     }
    75     return anc[x][0];
    76 }
    77 inline int query(const int &x,const int &y,const int &k) {
    78     const int z=lca(x,y);
    79     return ((sum[x][k]+sum[y][k]-sum[z][k]-sum[anc[z][0]][k])%mod+mod)%mod;
    80 }
    81 int main() {
    82     const int n=getint();
    83     for(register int i=1;i<n;i++) {
    84         add_edge(getint(),getint());
    85     }
    86     dfs(1,0); 
    87     for(register int i=getint();i;i--) {
    88         const int x=getint(),y=getint(),k=getint();
    89         printf("%d
    ",query(x,y,k));
    90     }
    91     return 0;
    92 }
  • 相关阅读:
    Microsoft Office MIME Types
    启动mongodb
    学习Hbase API的一个视频
    报错:Hive Runtime Error while processing row
    821. Shortest Distance to a Character
    1171. Remove Zero Sum Consecutive Nodes from Linked List
    190. Reverse Bits
    Rust--如何实现内存安全的?
    Rust -- as_ref与borrow的区别
    653. Two Sum IV
  • 原文地址:https://www.cnblogs.com/skylee03/p/8867108.html
Copyright © 2020-2023  润新知