刚结束的比赛
  • 板块学术版
  • 楼主Lele_Programmer
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/7/14 17:31
  • 上次更新2024/7/14 19:07:18
查看原帖
刚结束的比赛
961972
Lele_Programmer楼主2024/7/14 17:31

第三题怎么也调不出来,有大佬看看代码有什么问题吗:

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N=262149;
const int M=524293;
const int K=35;
const int inf=1e9;

typedef pair<int,int> pii;
typedef pair<int,pii> piii;

int n,m,dep;
int arr[N],arr_sum;
int e[M],ne[M],h[N],tot;
int f[N][K];
int g[N][K];
int layer[N];

void add(int a,int b) {
    e[tot]=b,ne[tot]=h[a],h[a]=tot++;
}

void dfs_brute(int u,int fa,int dis,unordered_set<int>& s) {
    s.insert(u);
    if (!dis) return;
    for (int i=h[u];~i;i=ne[i]) {
        if (e[i]==fa) continue;
        dfs_brute(e[i],u,dis-1,s);
    }
}

void dfs(int u,int fa) {
    f[u][0]=arr[u];
    for (int i=h[u];~i;i=ne[i]) {
        if (e[i]==fa) continue;
        dfs(e[i],u);
        for (int j=1;j<K;++j) {
            f[u][j]+=f[e[i]][j-1];
        }
    }
}

void bfs() {
    for (int i=1;i<=n;++i) layer[i]=inf;
    layer[0]=0;
    layer[1]=1;
    queue<int> q;
    q.push(1);
    while (!q.empty()) {
        int u=q.front(); q.pop();
        for (int i=h[u];~i;i=ne[i]) {
            if (layer[e[i]]!=inf) continue;
            q.push(e[i]);
            layer[e[i]]=layer[u]+1;
            g[e[i]][0]=u;
            for (int j=1;j<K;++j) {
                g[e[i]][j]=g[g[e[i]][j-1]][j-1];
            }
        }
    }
}

piii lca(int a,int b) {
    if (a==b) return {a,{0,0}};
    bool flag=false;
    if (layer[a]<layer[b]) {
        flag=true;
        swap(a,b);
    }
    int a_dis=0,b_dis=0;
    for (int i=K-1;~i;--i) {
        if (layer[g[a][i]]>=layer[b]) {
            a=g[a][i];
            a_dis+=1<<i;
        }
    }
    if (a==b) {
        if (flag) swap(a_dis,b_dis);
        return {a,{a_dis,b_dis}};
    }
    for (int i=K-1;~i;--i) {
        if (g[a][i]!=g[b][i]) {
            a=g[a][i];
            b=g[b][i];
            a_dis+=1<<i;
            b_dis+=1<<i;
        }
    }
    int ancestor=g[a][0];
    a_dis++,b_dis++;
    if (flag) swap(a_dis,b_dis);
    return {ancestor,{a_dis,b_dis}};
}

void debug() {
    for (int i=1;i<=n;++i) {
        for (int j=0;j<=dep;++j) {
            printf("f[%d][%d]=%d\n",i,j,f[i][j]);
        }
    }
}

signed main() {
    // freopen("test.in","r",stdin);
    // freopen("2.out","w",stdout);
    memset(h,-1,sizeof(h));
    scanf("%lld %lld",&dep,&m);
    n=(1<<dep)-1;
    for (int i=1;i<=n;++i) {
        scanf("%lld",&arr[i]);
        arr_sum+=arr[i];
    }
    for (int i=2;i<=n;++i) {
        add(i,i/2);
        add(i/2,i);
    }
    dfs(1,0);
    for (int i=1;i<=n;++i) {
        for (int j=1;j<K;++j) {
            f[i][j]+=f[i][j-1];
        }
    }
    // printf("test -1\n");
    bfs();
    // printf("test -2\n");
    // auto tmp=lca(2,7);
    // printf("lca(%d,%d) is %d %d %d\n",2,7,tmp.first,tmp.second.first,tmp.second.second);
    while (m--) {
        int a,b,c;
        scanf("%lld %lld %lld",&a,&b,&c);
        if (c>=2*(dep-1)) {
            printf("%lld\n",arr_sum);
            continue;
        }
        // printf("test 0\n");
        piii t=lca(a,b);
        if (t.second.first+t.second.second>2*c) {
            puts("0");
            continue;
        }
        int ans=0;
        if (t.second.first<=c && t.second.second<=c) ans+=arr[t.first];
        // printf("test 1\n");
        vector<int> vec;
        for (int i=b;i!=t.first;i>>=1) {
            vec.push_back(i);
        }
        reverse(vec.begin(),vec.end());
        int l=c-t.second.first-1,r=c-t.second.second-1;
        for (int i=0;i<((int)(vec.size()))-1;++i) {
            // cout<<vec[i]<<endl;
            int u=vec[i];
            if (l>=0) {
                ans+=arr[u];
                // printf("+%lld\n",arr[u]);
            }
            // cout<<(l>=0)<<endl;
            l--,r++;
            if (l<0) break;
            int v;
            if (vec[i+1]==(u<<1)) v=(u<<1|1);
            else v=(u<<1);
            if (min(l,r)<0) continue;
            // printf("f[%d][min(%d,%d)]=%d\n",v,l,r,f[v][min(l,r)]);
            ans+=f[v][min(l,r)];
        }
        // printf("test 2\n");
        swap(a,b);
        swap(t.second.first,t.second.second);
        vec.clear();
        for (int i=b;i!=t.first;i>>=1) {
            vec.push_back(i);
        }
        reverse(vec.begin(),vec.end());
        l=c-t.second.first-1,r=c-t.second.second-1;
        for (int i=0;i<((int)(vec.size()))-1;++i) {
            int u=vec[i];
            if (l>=0) {
                ans+=arr[u];
                // printf("+%lld\n",arr[u]);
            }
            l--,r++;
            if (l<0) break;
            int v;
            if (vec[i+1]==(u<<1)) v=(u<<1|1);
            else v=(u<<1);
            if (min(l,r)<0) continue;
            // printf("f[%d][min(%d,%d)]=%d\n",v,l,r,f[v][min(l,r)]);
            ans+=f[v][min(l,r)];
        }
        // cout<<"now ans: "<<ans<<endl;
        if (t.second.first+t.second.second<=c) {
            if (a!=t.first) ans+=f[a][c-t.second.second-t.second.first];
            if (b!=t.first) ans+=f[b][c-t.second.second-t.second.first];
        }
        // cout<<"now ans: "<<ans<<endl;
        // printf("test 3\n");
        if (layer[a]>layer[b]) {
            swap(a,b);
            swap(t.second.second,t.second.first);
        }
        if (a==t.first) {
            int i=b;
            while ((i>>1)!=a) {
                i>>=1;
            }
            int v;
            if ((a<<1)==i) v=(a<<1|1);
            else v=(a<<1);
            // printf("f[%d][min(%d,%d)]=%d\n",v,c-t.second.first-1,c-t.second.second-1,f[v][min(c-t.second.first-1,c-t.second.second-1)]);
            if (min(c-t.second.first-1,c-t.second.second-1)>=0) {
                ans+=f[v][min(c-t.second.first-1,c-t.second.second-1)];
            }
        }
        // cout<<"now ans: "<<ans<<endl;
        int last=t.first,u=(t.first>>1);
        l=c-t.second.first-1,r=c-t.second.second-1;
        while (u) {
            if (l>=0 && r>=0) {
                ans+=arr[u];
                // printf("+%lld\n",arr[u]);
            }
            l--,r--;
            if (l<0 || r<0) break;
            int v;
            if (last==(u<<1)) v=u<<1|1;
            else v=u<<1;
            // printf("f[%d][min(%d,%d)]=%d\n",v,l,r,f[v][min(l,r)]);
            // printf("%d %d\n",last,u);
            if (min(l,r)<0) break;
            ans+=f[v][min(l,r)];
            last=u;
            u>>=1;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

/*
4 1
3 4 10 7 1 6 10 6 16 5 3 16 6 2 9
3 15 1
*/

/*
4 1
3 4 10 7 1 6 10 6 16 5 3 16 6 2 9
4 2 1
11

4 1
3 4 10 7 1 6 10 6 16 5 3 16 6 2 9
1 14 5
74

4 1
3 4 10 7 1 6 10 6 16 5 3 16 6 2 9
6 13 3
51

4 1
3 4 10 7 1 6 10 6 16 5 3 16 6 2 9
2 6 5

4 1
3 4 10 7 1 6 10 6 16 5 3 16 6 2 9
10 11 5

4 1000
3 4 10 7 1 6 10 6 16 5 3 16 6 2 9
*/
2024/7/14 17:31
加载中...