The 2019 ACM-ICPC China Shannxi Provincial Programming Contest (西安邀请赛重现) J. And And And

链接:https://nanti.jisuanke.com/t/39277

思路:

一开始看着很像树分治,就用树分治写了下,发现因为异或操作的特殊性,我们是可以优化树分治中的容斥操作的,不合理的情况只有当两点在一条链上才存在,那么直接一遍dfs从根节点向下跑途中维护一下前缀和,把所有情况中不合理情况造成的值修正。

这样的话时间复杂度就可以降得非常低了,感觉还可以优化,但是懒得写了

代码耗时:142ms.

实现代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll M = 2e5+10;
const ll inf = 1e18+10;
struct node{
    ll to,next,w;
}e[M];
const ll mod = 1000000007;
struct node1{
    ll num,id;
}Xor[M];
bool cmp(node1 x,node1 y){
    return x.num < y.num;
}
vector<ll>mp[M],v[M];
ll cnt,n,ans;
ll head[M],sz[M],d[M],md[M];
void add(ll u,ll v,ll w){
    e[++cnt].to = v;e[cnt].w = w;e[cnt].next = head[u];head[u] = cnt;
}

map<ll,ll>sum,sum1,num;

void get_dis(ll u,ll fa){
    Xor[++Xor[0].num].num = d[u];
    Xor[Xor[0].num].id = u;
    for(ll i = head[u];i;i=e[i].next){
        ll v = e[i].to;
        if(v != fa){
            d[v] = d[u]^e[i].w;
            get_dis(v,u);
        }
    }
    return ;
}

void get_siz(ll u,ll fa){
    sz[u] = 1;
    for(ll i = head[u];i;i=e[i].next){
        ll v = e[i].to;
        if(v != fa){
            get_siz(v,u);
            sz[u] += sz[v];
        }
    }
}
void gcd(ll a,ll b,ll &d,ll &x,ll &y)
{
    if(!b) {d=a;x=1;y=0;}
    else {gcd(b,a%b,d,y,x);y-=x*(a/b);}
}
ll finv(ll a,ll n)
{
  ll d,x,y;
  gcd(a,n,d,x,y);
  return d==1?(x+n)%n:-1;
}
void cal(ll u){
    d[u] = 0; Xor[0].num = 0;
    get_dis(u,0);
    sort(Xor+1,Xor+1+Xor[0].num,cmp);
    ll st = -1,idx = 0;
    for(ll i = 1;i <= Xor[0].num;i ++){
        if(Xor[i].num != st){
            st = Xor[i].num;
            mp[++idx].push_back(Xor[i].id);
            md[idx] = st;
        }
        else{
            mp[idx].push_back(Xor[i].id);
        }
    }
    ans = 0;
    for(ll i = 1;i <= idx;i ++){
        ll num1 = 0,num2 = 0;
        for(ll j = 0;j < mp[i].size();j ++){
            num1 += sz[mp[i][j]];
            num2 += sz[mp[i][j]]*sz[mp[i][j]]%mod;
            num1%=mod;     num2%=mod;
        }
        ans += ((num1*num1%mod+mod - num2)%mod)*finv(2,mod)%mod;
        ans %= mod;
    }
    for(ll i = 1;i <= idx;i ++) mp[i].clear();
}

void dfs(ll u,ll fa){
    for(ll i = head[u];i;i=e[i].next){
        ll v = e[i].to;
        if(v == fa) continue;
        sum1[d[u]] += (n - sz[v]+mod)%mod;
        if(num[d[v]] >= 1){
            ans = (ans + mod - (sz[v]*sum[d[v]]%mod))%mod;
            ans += sz[v]*sum1[d[v]]%mod;
            ans %= mod;
        }
        sum[d[v]] += sz[v];
        num[d[v]] += 1;
        sum[d[v]]%=mod;
        sum1[d[v]]%=mod;
        dfs(v,u);
        sum[d[v]] -= sz[v]-mod;
        sum1[d[u]] -= (n-sz[v])-mod;
        sum[d[v]]%=mod;
        sum1[d[v]]%=mod;
        num[d[v]] -= 1;
    }
}

int main()
{
    ll v,w;
    scanf("%lld",&n);
    for(ll i = 2;i <= n;i ++){
        scanf("%lld%lld",&v,&w);
        add(i,v,w); add(v,i,w);
    }
    get_siz(1,0);
    cal(1);
    sum[0] += sz[1];
    num[0] += 1;
    dfs(1,0);
    ans %= mod;
    num.clear(); sum.clear(); sum1.clear();
    printf("%lld\n",ans);
}

原文地址:https://www.cnblogs.com/kls123/p/10943213.html

时间: 2024-08-30 09:53:13

The 2019 ACM-ICPC China Shannxi Provincial Programming Contest (西安邀请赛重现) J. And And And的相关文章

The 2018 ACM-ICPC China JiangSu Provincial Programming Contest快速幂取模及求逆元

题目来源 The 2018 ACM-ICPC China JiangSu Provincial Programming Contest 35.4% 1000ms 65536K Persona5 Persona5 is a famous video game. In the game, you are going to build relationship with your friends. You have N friends and each friends have his upper b

The 2018 ACM-ICPC China JiangSu Provincial Programming Contest(第六场)

A Plague Inc Plague Inc. is a famous game, which player develop virus to ruin the world. JSZKC wants to model this game. Let's consider the world has N×Mimes MN×M cities. The world has N rows and M columns. The city in the X row and the Y column has

2019 ACM ICPC 南京站 H. Prince and Princess

题意 王子想要娶公主,但是需要完成一个挑战:在一些房间中找出公主在哪. 每个房间有一个人,他们彼此知道谁在哪个房间.可以问他们三种问题: 你是谁? 在某个房间是谁? 公主在哪个房间? 有三类人,一类一定说真话,一类一定说假话,一类可能说真话可能说假话. 王子知道这三类人的人数分别为 \(a\), \(b\), \(c\),求能否通过问一些问题找到公主在哪,如果能,输出最少需要的问题数. 思路 第三类人有可能说假话,因此最坏情况就是说假话,所以把他们视为第二类人. 首先问所有人第三个问题,那么最坏

Fire-Fighting Hero (The 2019 Asia Nanchang First Round Online Programming Contest)

This is an era of team success, but also an era of heroes. Throughout the ages, there have been numerous examples of using the few to defeat the many. There are VV(Numbers 11 to VV) fire-fighting points in ACM city. These fire-fighting points have EE

The 2019 Aisa Nanchang First Round Online Programming Contest ——H

思路:矩阵快速幂+map 代码: #include<cmath> #include<algorithm> #include<cstdio> #include<map> const int INF=0x3f3f3f3f; const int maxn = 1e7+10; const int mod=998244353; using namespace std; typedef long long ll; map<ll,ll> mp; ll n; s

Pangu Separates Heaven and Earth(签到题)(The 2019 Asia Nanchang First Round Online Programming Contest)

Long long ago, the sky and the earth were not separated, and the universe was chaotic. There was a giant named Pangu who slept for eighteen thousand years in this chaos. One day, Pangu woke up suddenly. When he saw the darkness around him, he took up

H. The Nth Item(The 2019 Asia Nanchang First Round Online Programming Contest)

题意:https://nanti.jisuanke.com/t/41355 给出N1,计算公式:A=F(N)Ni=Ni-1 ^ (A*A),F为类斐波那契需要矩阵快速幂的递推式. 求第k个N. 思路: 发现从大约1e5个数开始N交替出现,到一定位置%2即可.(or正解:https://blog.csdn.net/qq_41848675/article/details/100667808   or https://blog.csdn.net/jk_chen_acmer/article/detail

The 2019 Asia Nanchang First Round Online Programming Contest E. Magic Master

题目链接:https://nanti.jisuanke.com/t/41352 题目意思还是好理解的,看过的人不多,感觉是被通过量吓到了.其实就是个水题,反向模拟就好了, 用队列模拟,反向模拟,它要放m张卡到后面,那我就放m张卡到前面,一开始队列只有1张卡,慢慢加到n张卡, 先加大的卡,再一直到1的卡.对了,可能会出现只有5张卡,m却是6,7,8或9,10,那么为了减少不必要的模拟, 用mod来减少,因为有些模拟会让卡和之前比较,算是原封不动. 1 #include <iostream> 2

The 2019 Asia Nanchang First Round Online Programming Contest The Nth Item

The Nth Item 思路: 先用特征根法求出通向公式,然后通向公式中出现了\(\sqrt{17}\),这个可以用二次剩余求出来,然后可以O(\(log(n)\))求出. 但是还不够,我们先对\(n\)欧拉降幂,然后求base为\(\sqrt{1e9}\)的快速幂,预处理一些东西,就可以类似O(1)求出了. 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/std