zoukankan      html  css  js  c++  java
  • BJOI 2012 求和

    https://www.luogu.org/problemnew/show/P4427

    因为这个题,我交了整整两页...

    题目不难,预处理+lca

    一个奇坑点:预处理sum的时候,你是不能取模的,因为有可能取模之后sum值变小,而实际上不是,由于你后一步还要做减法

    因此就会出锅,导致我爆零一整页正确做法是最后取模,虽然我也不知道为什么这样不会爆炸,300000 * 998244353这都死哪儿去了...

    真是血一般的教训啊,取模不能乱取

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<climits>
    #include<vector>
    #include<cstdlib>
    #include<ctime>
    #include<queue> 
    using namespace std;
    #define mod 998244353
    #define maxn 300000 + 10
    typedef long long ll;
    inline ll read()
    {
        ll ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    ll power(ll a,ll b)
    {
        ll ans = 1,res = a;
        while(b)
        {
            if(b & 1)
                (ans *= res) %= mod;
            (res *= res) %= mod;
            b = b >> 1;
        }
        return ans % mod;
    }
    struct edge
    {
        ll to,next;
    }e[maxn << 1];
    ll fir[maxn],alloc;
    void adde(ll u,ll v)
    {
        e[++alloc].next = fir[u];
        fir[u] = alloc;
        e[alloc].to = v;
        swap(u,v);
        e[++alloc].next = fir[u];
        fir[u] = alloc;
        e[alloc].to = v;
    }
    ll sum[maxn][60];
    ll dep[maxn],f[maxn][31];
    void dfs(ll u,ll fa)
    {
        dep[u] = dep[fa] + 1;
        f[u][0] = fa;
        for(int i = 1;i <= 50;i++)
            sum[u][i] = sum[fa][i] + power(dep[u],i);
        for(int i = 1;i <= 20;i++)
            f[u][i] = f[f[u][i - 1]][i - 1];
        for(int i = fir[u];i;i = e[i].next)
        {
            ll v = e[i].to;
            if(v == fa) continue;
            dfs(v,u);
        }
    }
    ll lca(ll x,ll y)
    {
        if(dep[x] < dep[y]) swap(x,y);
        for(int i = 19;i >= 0;i--)
        {
            if(dep[f[x][i]] >= dep[y]) x = f[x][i];
            if(x == y) return x;
        }
        for(int i = 19;i >= 0;i--)
        {
            if(f[x][i] != f[y][i])
            {
                x = f[x][i];
                y = f[y][i];
            }
        }
        return f[x][0];
    }
    ll n,m; 
    int main()
    {
        n = read();
        for(int i = 1;i <= n - 1;i++)
        {
            ll u = read(),v = read();
            adde(u,v);
        }
        dep[0] = -1; 
        dfs(1,0); 
        m = read();
        for(int i = 1;i <= m;i++)
        {
            ll u = read(),v = read(),k = read();
            ll to = lca(u,v);
            printf("%lld
    " , ((sum[u][k] + sum[v][k]) - (sum[to][k] + sum[f[to][0]][k])) % mod);
        }
    }

     

  • 相关阅读:
    Android 图片圆角、图片圆形【转载:https://github.com/SheHuan/NiceImageView】
    fragment中嵌套listview,切换时数据出现重复加载
    fragment中嵌套listview,切换时数据出现重复加载
    Android让View的显示超出父容器
    ZooKeeper
    Redis
    kafka
    性能优化一
    RK Android7.1 禁用 USB触摸
    RK Android7.1 使用POWER按键才能开机
  • 原文地址:https://www.cnblogs.com/LM-LBG/p/10343580.html
Copyright © 2011-2022 走看看