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

思路:

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

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

代码耗时:142ms.

实现代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll M = 2e5+;
const ll inf = 1e18+;
struct node{
ll to,next,w;
}e[M];
const ll mod = ;
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[].num].num = d[u];
Xor[Xor[].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] = ;
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=;y=;}
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==?(x+n)%n:-;
}
void cal(ll u){
d[u] = ; Xor[].num = ;
get_dis(u,);
sort(Xor+,Xor++Xor[].num,cmp);
ll st = -,idx = ;
for(ll i = ;i <= Xor[].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 = ;
for(ll i = ;i <= idx;i ++){
ll num1 = ,num2 = ;
for(ll j = ;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(,mod)%mod;
ans %= mod;
}
for(ll i = ;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]] >= ){
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]] += ;
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]] -= ;
}
} int main()
{
ll v,w;
scanf("%lld",&n);
for(ll i = ;i <= n;i ++){
scanf("%lld%lld",&v,&w);
add(i,v,w); add(v,i,w);
}
get_siz(,);
cal();
sum[] += sz[];
num[] += ;
dfs(,);
ans %= mod;
num.clear(); sum.clear(); sum1.clear();
printf("%lld\n",ans);
}

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

  1. 计蒜客 39272.Tree-树链剖分(点权)+带修改区间异或和 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest E.) 2019ICPC西安邀请赛现场赛重现赛

    Tree Ming and Hong are playing a simple game called nim game. They have nn piles of stones numbered  ...

  2. C.0689-The 2019 ICPC China Shaanxi Provincial Programming Contest

    We call a string as a 0689-string if this string only consists of digits '0', '6', '8' and '9'. Give ...

  3. B.Grid with Arrows-The 2019 ICPC China Shaanxi Provincial Programming Contest

    BaoBao has just found a grid with $n$ rows and $m$ columns in his left pocket, where the cell in the ...

  4. 计蒜客 39280.Travel-二分+最短路dijkstra-二分过程中保存结果,因为二分完最后的不一定是结果 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest M.) 2019ICPC西安邀请赛现场赛重现赛

    Travel There are nn planets in the MOT galaxy, and each planet has a unique number from 1 \sim n1∼n. ...

  5. 计蒜客 39279.Swap-打表找规律 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest L.) 2019ICPC西安邀请赛现场赛重现赛

    Swap There is a sequence of numbers of length nn, and each number in the sequence is different. Ther ...

  6. 计蒜客 39270.Angel's Journey-简单的计算几何 ((The 2019 ACM-ICPC China Shannxi Provincial Programming Contest C.) 2019ICPC西安邀请赛现场赛重现赛

    Angel's Journey “Miyane!” This day Hana asks Miyako for help again. Hana plays the part of angel on ...

  7. 计蒜客 39268.Tasks-签到 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest A.) 2019ICPC西安邀请赛现场赛重现赛

    Tasks It's too late now, but you still have too much work to do. There are nn tasks on your list. Th ...

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

    题目来源 The 2018 ACM-ICPC China JiangSu Provincial Programming Contest 35.4% 1000ms 65536K Persona5 Per ...

  9. The 2018 ACM-ICPC China JiangSu Provincial Programming Contest J. Set

    Let's consider some math problems. JSZKC has a set A=A={1,2,...,N}. He defines a subset of A as 'Meo ...

随机推荐

  1. python中闭包的概念

    闭包:简单来说,就是一个外部函数的返回值是内部函数的引用 通过一个例子来说明 def outer(a): b = 10 def inner(): print(a+b) return inner   # ...

  2. Activiti服务类- FormService服务类

    转自:https://www.cnblogs.com/liuqing576598117/p/9814953.html 1.获取//通过流程定义ID获取表单字段集合StartFormData start ...

  3. Shell 02 数据运算/条件测试

    一.整数运算工具 1.使用expr命令(运算两边必须有空格,引用变量时必须加$符号) [root@svr5 ~]# x=10    //定义变量x expr $x + 10      20       ...

  4. JVM备忘点(1.8以前)

    1.内存结构 左边两个线程共享,右边三个线程私有. 方法区:.class文件的类信息.常量.static变量.即时编译器编译后的代码(动态代理).HotSpot将方法区称为永久代 堆:分为新生代和老年 ...

  5. c++ 排序,<< 运算符重载

    #include <iostream> #include <functional> #include <list> using namespace std; ost ...

  6. 使用axios请求的坑

    配置axios在vue-cli中的使用: 在main.js中配置 import axios from "axios" Vue.config.productionTip = fals ...

  7. @EnableTransactionManagement的使用

    Spring Boot 使用事务非常简单,首先使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问数据库的Service方法上添加注解 @Transactio ...

  8. 如何捕捉Desried Capabilities中的appPackafe和appActive

    捕捉这两个参数需要借助adb工具的日志进行分析.ADB是一种命令行工具,用于PC和Android模拟器之前连接通信,集成在Android ADK中,默认在platfrom-tools目录下.在cmd运 ...

  9. oracle-sql脚本

    select * from dba_users; create tablespace kyc_coo; create user kyc_coo identified by "123456&q ...

  10. Kali Linux更新5.2.9后 Vmware Workstation无法正常启动

    说明本脚本仅作为学习使用,请勿用于任何商业用途.本文为原创,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 最近更新了Kali后发现一个奇葩的问题,我的虚拟机不能正常使用了.启 ...