van老师的题

题目质量很高,第二题提供了一个很好的解决同一类问题的思路

把每个点的权值赋在它的到父亲的那条条边 本题的主要思想是利用二进制位变换的周期性进行倍增然后求解,十分精妙,明天再打一遍

这道题大意是求一棵树上u到v的路径上的所有点dis(u,w)|val[w]的和,利用二进制变换的周期性来进行倍增.

//把每个点的权值赋在它的到父亲的那条条边 
// 本题的主要思想是利用二进制位变换的周期性进行倍增然后求解,十分精妙,明天再打一遍 
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

typedef long long LL;

const LL N = 500005 , M = N * 2 , Bi = 21;

LL n , m , ne[M] , fir[N] , to[M] , val[N] , st[N][Bi] , up[N][Bi] , dn[N][Bi] , u , v , x , y , cnt = 1 , depth[N] , Get[N][Bi] , fa[N];

#define Foreachson(i , x) for(LL i = fir[x];i;i = ne[i])

void link(LL x ,LL y) {
    ne[++ cnt] = fir[x]; fir[x] = cnt; to[cnt] = y; ne[++ cnt] = fir[y]; fir[y] = cnt; to[cnt] = x;
}

void dfs(LL x , LL f) {
    fa[x] = f; depth[x] = depth[f] + 1;
    for(LL i = 0;i < Bi;i ++) Get[x][i] += Get[f][i] , Get[x][i] += ((val[x] & (1 << i)) == 0) * (1 << i);
    st[x][0] = f; for(LL i = 1;i < Bi;i ++) st[x][i] = st[st[x][i - 1]][i - 1]; up[x][0] = val[x]; dn[x][0] = val[x];
    for(LL i = 1;i < Bi;i ++) {
        LL it = st[x][i - 1];
        up[x][i] = up[x][i - 1] + up[it][i - 1] + Get[it][i - 1] - Get[st[x][i]][i - 1];
        dn[x][i] = dn[x][i - 1] + dn[it][i - 1] + Get[x][i - 1] - Get[it][i - 1];
    }
    Foreachson(i , x) if(to[i] != f) dfs(to[i] , x);
}

LL LCA(LL x , LL y) {
    if(depth[y] < depth[x]) swap(x , y);
    for(LL i = Bi - 1;i >= 0;i --) if(depth[x] <= depth[st[y][i]]) y = st[y][i];
    if(x == y) return x;
    for(LL i = Bi - 1;i >= 0;i --) if(st[x][i] != st[y][i]) x = st[x][i] , y = st[y][i];
    return st[x][0];
}

LL upcalc(LL x , LL l) {
    LL res = 0; l = fa[l];
    for(LL i = 20; ~i;i --) {
        if(depth[st[x][i]] >= depth[l]) {
            res += up[x][i];
            x = st[x][i];
            res += Get[x][i] - Get[l][i];
        }
    }
    return res;
}

LL dncalc(LL x , LL d) {
    LL res = 0; LL s = x;  d++;
    for(LL i = 0;i <= 20;i ++) {
        if(d & (1 << i)) {
            res += dn[x][i];
            res += Get[s][i] - Get[x][i];
            x = st[x][i];
        }
    }
    return res;
}

LL calc(LL x , LL y) {
    LL lca = LCA(x , y)   , d = depth[x] + depth[y] - depth[lca] * 2;
    return upcalc(x , lca) + dncalc(y , d) - dncalc(lca , depth[x] - depth[lca]);
}

main(void) {
    scanf("%lld",&n);
    for(LL i = 1;i <= n;i ++) scanf("%lld",&val[i]);
    for(LL i = 1;i <= n - 1;i ++) scanf("%lld%lld",&x,&y) , link(x , y);
    dfs(1, 0); LL t; scanf("%lld",&t);
    for(LL i = 1;i <= t;i ++) {
        scanf("%lld%lld",&u,&v);
        printf("%lld\n" , calc(u,v));
    }
}

第三题是一道KMP上套DP的题,以后遇到这种题利用next数组的性质可以大胆的猜想一发等价的结论.

#include<cstdio>
#include<cstring>
using namespace std;
const int N = 500005; int dp[N] , ne[N]  , match[N] , len; char s[N];
int main(void) {
    scanf("%s",s + 1); len = strlen(s + 1); int j , i;puts("1");
    for(i = 2,ne[0] = -1 , dp[1] = match[1] = 1, j = 0;i <= len;printf("%d\n",dp[i]) , i++) {
        while(j != -1 && s[i] != s[j + 1]) j = ne[j]; ne[i] = ++j;
        if(match[dp[ne[i]]] + ne[i] >= i) dp[i] = dp[ne[i]] , match[dp[i]] = i; else dp[i] = i , match[i] = i;
    }
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看rEADME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看rEADME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通;、 3本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看ReAdmE.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值