[数学] Codechef September Challenge 2017 Weasel does Xor on Tree

本文介绍了一种使用深度优先搜索(DFS)遍历树结构,并结合组合数原理来解决特定问题的方法。通过递归地计算每个节点的深度及路径上的节点数,实现了对于特定查询的有效处理。

fi,j 表示时间为 i 的时候,j 点的权值

那么 fi,u=XOR{fi1,v|vsonu}

fi1,vfi1,v 带入不断展开

就可以得到 fx,1=XOR{aif0,i} ,其中 aif0,i 表示 aif0,i 异或起来

手动展开一下发现这个系数就跟这个点的深度有关,可以递推得到

并且 ai 的递推形式就跟组合数的递推形式一样。

推一推就可以知道 ai=(depth+x2depth1)

显然当 ai 为奇数的时候,点 i 才有贡献。

考虑lucas定理,也就是说 depth1 的二进制要是 depth+x2 的子集

再转化就是 x1depth1 没有重合,也就是and起来为0

然后就3logn 子集统计一下就好了

x 很大,但是只有 x 前面的一段二进制位是有用的, x2log2n 取模就可以了

UPD:子集统计可以用高维前缀和,复杂度就降到了 nlogn

#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;

const int N=1000010;

int n,m,cnt,imax,fa[N],dpt[N],G[N];
ll a[N];
struct iedge{
    int t,nx;
}E[N<<1];

inline void addedge(int x,int y){
    E[++cnt].t=y; E[cnt].nx=G[x]; G[x]=cnt;
    E[++cnt].t=x; E[cnt].nx=G[y]; G[y]=cnt;
}

int it;

void dfs(int x,int f){
    fa[x]=f; dpt[x]=dpt[f]+1;
    imax=max(imax,dpt[x]);
    for(int i=G[x];i;i=E[i].nx)
        if(E[i].t!=f) dfs(E[i].t,x);
}
inline int C(int x,int y){
    if(!x && !y) return 1;
    if(!(x&1) && (y&1)) return 0;
    return C(x/2,y/2);
}

ll f[N],g[N];

void PutAns(ll x){
    if(x>=10) PutAns(x/10); putchar(x%10+'0');
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1,x,y;i<n;i++)
        scanf("%d%d",&x,&y),addedge(x+1,y+1);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    dfs(1,0);
    int NN=1; while(NN<imax) NN<<=1; NN--;
    for(int i=1;i<=n;i++) f[dpt[i]-1]^=a[i];
    /*for(int i=0;i<=NN;i++){
        g[i]^=f[0];
        for(int j=NN-i;j;j=(j-1)&(NN-i)) 
            g[i]^=f[j];
    }
    while(m--){
        ll x; scanf("%lld",&x);
        if(x==0) PutAns(a[1]);
        else PutAns(g[(x-1)%(NN+1)]); putchar('\n');
    }*/

    for(int i=0;i<=17;i++)
        for(int j=0;j<=NN;j++)
            if(~j>>i&1) f[j|(1<<i)]^=f[j];
    while(m--){
        ll x; scanf("%lld",&x);
        if(x==0) PutAns(a[1]);
        else PutAns(f[NN-(x-1)%(NN+1)]); putchar('\n');
    }
}
### WEASEL 和 MUSE 的概述 WEASEL (Word ExtrAction for time SEries cLassification) 是一种用于时间序列分类的方法,它通过提取词袋特征来表示时间序列数据[^1]。具体来说,WEASEL 将时间序列分割成多个窗口,并利用离散化技术将其转化为字符序列。随后,这些字符序列被进一步映射到单词空间中,形成高维稀疏向量作为输入给机器学习模型。 MUSE (Multivariate Unsupervised Symbols and dErivatives) 则扩展了单变量时间序列分析方法至多变量场景下。对于每条独立的时间序列维度,MUSE 都会单独执行类似于 WEASEL 的操作;之后再综合各个维度上的结果得到最终表达形式[^2]。 两者结合可以应用于更广泛的任务领域比如自然语言处理(NLP),其中涉及到了文本挖掘以及模式识别等方面的知识和技术手段的应用实例: - **时间序列预处理阶段**:采用滑动窗机制完成原始信号片段截取工作; - **特征工程环节**:运用傅里叶变换或者小波分解等方式实现频域特性捕捉; - **降噪与标准化过程**:去除噪声干扰因素影响的同时保持物理意义不变; 最后将上述所得数值型属性集合送入支持向量机(SVM),随机森林(Random Forests)等传统监督式学习框架当中训练预测模型并评估效果好坏程度如何变化趋势等问题都需要深入探讨研究下去才行[^3]。 ```python from sklearn.feature_extraction.text import CountVectorizer import numpy as np def weasel_transform(series, window_size=10): """Transform a univariate time series into bag-of-pattern features.""" words = [] for i in range(len(series)-window_size+1): segment = series[i:i+window_size] word = ''.join(['a' if s >= np.mean(segment) else 'b' for s in segment]) words.append(word) vectorizer = CountVectorizer() X = vectorizer.fit_transform(words).toarray() return X time_series_data = [np.random.rand(100)] X_weasel = weasel_transform(time_series_data[0]) print(X_weasel.shape) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值