【2019ICPC西安邀请赛】J.And And And(点分治)
时间:2019-10-15
本文章向大家介绍【2019ICPC西安邀请赛】J.And And And(点分治),主要包括【2019ICPC西安邀请赛】J.And And And(点分治)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题意:给定一棵n个点带边权的树,定义每条路径的值为路径上边权的异或和
如果一条路径的值为0,其对答案的贡献为所有包含这条路径的路径条数
求答案膜1e9+7
n<=1e5,0<=边权<=1e18
思路:参考https://dudulu.net/blog/?p=1654
考场上还剩2小时的时候开的这题,乍一看觉得很可做就是个裸的点分,结果发现自己不会算贡献,场上连样例都没调出来
现在也是写了两天发现不会算贡献,参考了dalao的博客才会
每条路径的权值可以用两个端点分别能扩展的点的个数的乘积来算
预处理一下以1为根每个点的父亲和子树大小
在分治过程中,假设有u->……->pre->v这条路径
对于v这个点:
如果pre=f[v]可扩展的个数就是siz[v]
若果pre!=f[v]可扩展的个数就是n-siz[pre]
对于分治中心u和u的每个直接分支v:
如果u=f[v]可扩展的个数就是n-siz[v]
如果u!=f[v]可扩展的个数就是siz[u]
扔到map里记一下前缀和
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typedef pair<ll,ll> Pll; 8 typedef vector<int> VI; 9 typedef vector<PII> VII; 10 //typedef pair<ll,ll>P; 11 #define N 200010 12 #define M 200010 13 #define fi first 14 #define se second 15 #define MP make_pair 16 #define pb push_back 17 #define pi acos(-1) 18 #define mem(a,b) memset(a,b,sizeof(a)) 19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 21 #define lowbit(x) x&(-x) 22 #define Rand (rand()*(1<<16)+rand()) 23 #define id(x) ((x)<=B?(x):m-n/(x)+1) 24 #define ls p<<1 25 #define rs p<<1|1 26 27 const ll MOD=1e9+7,inv2=(MOD+1)/2; 28 double eps=1e-6; 29 ll INF=1e15; 30 int dx[4]={-1,1,0,0}; 31 int dy[4]={0,0,-1,1}; 32 33 struct node 34 { 35 int x; 36 ll y; 37 }q[N]; 38 39 map<ll,ll>mp1,mp2; 40 map<ll,ll>::iterator it; 41 int head[N],vet[N],nxt[N],c[N],flag[N],son[N], 42 s[N],siz[N],f[N],pre[N],tot,root,sum,n,now; 43 ll len[N],dis[N],ans; 44 45 int read() 46 { 47 int v=0,f=1; 48 char c=getchar(); 49 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 50 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 51 return v*f; 52 } 53 54 void add(int a,int b,ll c) 55 { 56 nxt[++tot]=head[a]; 57 vet[tot]=b; 58 len[tot]=c; 59 head[a]=tot; 60 } 61 62 void getroot(int u,int fa) 63 { 64 son[u]=1; c[u]=0; 65 int e=head[u]; 66 while(e) 67 { 68 int v=vet[e]; 69 if(v!=fa&&!flag[v]) 70 { 71 getroot(v,u); 72 son[u]+=son[v]; 73 c[u]=max(c[u],son[v]); 74 } 75 e=nxt[e]; 76 } 77 c[u]=max(c[u],sum-c[u]); 78 if(c[u]<c[root]) root=u; 79 } 80 81 void dfs(int u,int fa) 82 { 83 siz[u]=1; 84 int e=head[u]; 85 while(e) 86 { 87 int v=vet[e]; 88 if(v!=fa) 89 { 90 f[v]=u; 91 dfs(v,u); 92 siz[u]+=siz[v]; 93 } 94 e=nxt[e]; 95 } 96 } 97 98 void getdis(int u,int fa) 99 { 100 if(fa==f[u]) 101 { 102 mp1[dis[u]]=(mp1[dis[u]]+siz[u])%MOD; 103 if(dis[u]==0) ans=(ans+1ll*siz[u]*now%MOD)%MOD; 104 } 105 else 106 { 107 mp1[dis[u]]=(mp1[dis[u]]+n-siz[fa])%MOD; 108 if(dis[u]==0) ans=(ans+1ll*(n-siz[fa])*now%MOD)%MOD; 109 } 110 int e=head[u]; 111 while(e) 112 { 113 int v=vet[e]; 114 if(v!=fa&&!flag[v]) 115 { 116 dis[v]=dis[u]^len[e]; 117 getdis(v,u); 118 } 119 e=nxt[e]; 120 } 121 } 122 123 void calc(int u) 124 { 125 dis[u]=0; 126 int e=head[u]; 127 while(e) 128 { 129 int v=vet[e]; 130 if(flag[v]) 131 { 132 e=nxt[e]; 133 continue; 134 } 135 mp1.clear(); 136 if(f[v]==u) now=n-siz[v]; 137 else now=siz[u]; 138 dis[v]=len[e]; 139 getdis(v,u); 140 it=mp1.begin(); 141 while(it!=mp1.end()) 142 { 143 ll w=it->fi,t=it->se; 144 ans=(ans+t*mp2[w]%MOD)%MOD; 145 it++; 146 } 147 it=mp1.begin(); 148 while(it!=mp1.end()) 149 { 150 ll w=it->fi,t=it->se; 151 mp2[w]=(mp2[w]+t)%MOD; 152 it++; 153 } 154 e=nxt[e]; 155 } 156 mp2.clear(); 157 } 158 159 void solve(int u) 160 { 161 flag[u]=1; 162 calc(u); 163 int e=head[u]; 164 while(e) 165 { 166 int v=vet[e]; 167 if(!flag[v]) 168 { 169 sum=son[v]; root=0; 170 getroot(v,0); 171 solve(root); 172 } 173 e=nxt[e]; 174 } 175 } 176 177 int main() 178 { 179 //freopen("1.in","r",stdin); 180 //freopen("1.out","w",stdout); 181 n=read(); 182 rep(i,1,n) head[i]=flag[i]=0; 183 tot=0; 184 rep(i,2,n) 185 { 186 int x=read(); 187 ll y; 188 scanf("%lld",&y); 189 add(i,x,y); 190 add(x,i,y); 191 } 192 dfs(1,0); 193 sum=n; c[0]=n; ans=0; root=0; 194 getroot(1,0); 195 solve(root); 196 printf("%lld\n",ans); 197 return 0; 198 }
原文地址:https://www.cnblogs.com/myx12345/p/11678248.html
- WordPress 4.6远程代码执行漏洞(CVE-2016-10033)复现环境搭建指南
- 相似文档查找算法之 simHash 简介及其 java 实现
- Hadoop 中利用 mapreduce 读写 mysql 数据
- Android O中对TEE加解密算法的新要求
- storm 原理简介及单机版安装指南
- Python Tips, Tricks, and Hacks
- 英特尔放出Linux微代码以修复Meltdown和Spectre漏洞
- python基础(5):深入理解 python 中的赋值、引用、拷贝、作用域
- Linux SSH密码暴力破解技术及攻防实战
- 西部数据NAS设备被曝存在硬编码后门和未授权文件上传高危漏洞
- Hive & Performance 学习笔记
- 任意用户密码重置(一):重置凭证泄漏
- linux 系统监控、诊断工具之 top 详解
- 一个二进制POC的诞生之旅CVE-2018-0802
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 五分钟C语言数据结构 之 二叉树后序遍历(非递归很重要)
- 5分钟Flink - 自定义Source源
- 9.深入k8s:调度器及其源码分析
- 5分钟Flink - 自定义Data Sink
- 5分钟Flink - 流处理API转换算子集合
- 视频上云/网络穿透/网络映射服务EasyNTS前端组织添加页面出现Vue冲突怎么解决?
- Pinpoint 一款强大的APM工具
- 1. Pandas系列 - 基本数据结构
- 6 年前,只会 JSP 和 Servlet 就可以找到工作
- Python文件处理实用指南
- 2. Pandas系列 - Series基本功能
- 1.3 广告算法专题 - 交叉验证
- 最好用的内网穿透工具合集
- JVM垃圾回收之垃圾回收器,程序员必须掌握的知识
- 5分钟Flink - 时间与语义案例详解