Problem Digit Tree

题目大意

  给一棵树,有边权1~9。

  询问有多少个点对(i,j),将i--j路径上的数字依次连接后所形成新数字可以被k整除。gcd(K,10)=1

解题分析

  点分治。考虑某一次分治,根为rt,求出所有子节点到根所形成数字为A,根到所有子节点所形成数字为B。

  那么即求出所有满足 ( A[i] * 10 ^ B[j] . len + B[j] ) % K == 0的点对。
  转化后为 A[i] == (K - B[j]) * 10 ^ ( - B[j] . len ) , 用map处理一下即可。

参考程序

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std; #define N 100008
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define clr(x,v) memset(x,v,sizeof(x));
#define bitcnt(x) __builtin_popcount(x)
#define rep(x,y,z) for (int x=y;x<=z;x++)
#define repd(x,y,z) for (int x=y;x>=z;x--)
const int mo = ;
const int inf = 0x3f3f3f3f;
const int INF = ;
/**************************************************************************/ int n,m,phi;
int lt[N],size[N],f[N],vis[N],a[N],b[N],sum,tot,root,pre1[N],pre2[N];
LL ans,Alltmp;
map <int,int> mp;
struct edge{int u,v,w,nt;}eg[N*];
void add(int u,int v,int w){
eg[++sum]=(edge){u,v,w,lt[u]}; lt[u]=sum;
}
LL quick(LL x,LL y)
{
LL res=;
while (y)
{
if (y & ) res=res*x % m;
x=x*x % m;
y>>=;
}
return res;
}
void init()
{
int mm=m;
phi=m;
for (int i=;i*i<=m;i++)
{
if (mm % i==)
{
while (mm % i==) mm/=i;
phi=phi/i*(i-);
}
}
if (mm>) phi=phi/mm*(mm-);
clr(lt,); sum=;
clr(f,); f[]=INF;
clr(vis,);
ans=;
pre1[]=; pre2[]=;
rep(i,,)
{
pre1[i]=1ll*pre1[i-]* % m;
pre2[i]=quick(pre1[i],phi-);
}
}
void getRoot(int u,int fa)
{
size[u]=; f[u]=;
for (int i=lt[u];i;i=eg[i].nt)
{
int v=eg[i].v;
if (vis[v] || v==fa) continue;
getRoot(v,u);
size[u]+=size[v];
f[u]=max(f[u],size[v]);
}
f[u]=max(f[u],tot-size[u]);
if (f[u]<f[root]) root=u;
}
void getA(int u,int fa,int len)
{
for (int i=lt[u];i;i=eg[i].nt)
{
int v=eg[i].v;
if (vis[v] || v==fa) continue;
a[v]=(1ll*eg[i].w*pre1[len]+a[u]) % m;
getA(v,u,len+);
}
Alltmp+=mp[a[u]];
int tp=(m-b[u]) % m;
tp=1ll*tp*pre2[len] % m;
if (a[u]==tp) Alltmp--;
}
void getB(int u,int fa,int len)
{
int tp=(m-b[u]) % m;
tp=1ll*tp*pre2[len]% m;
mp[tp]++;
for (int i=lt[u];i;i=eg[i].nt)
{
int v=eg[i].v;
if (vis[v] || v==fa) continue;
b[v]=(1ll*b[u]*+eg[i].w) % m;
getB(v,u,len+);
}
}
LL calc(int u,int key)
{
key%=m;
Alltmp=; mp.clear();
a[u]=b[u]=key;
getB(u,,key==?:); getA(u,,key==?:);
return Alltmp;
}
void solve(int u)
{
ans+=calc(u,); vis[u]=;
for (int i=lt[u];i;i=eg[i].nt)
{
int v=eg[i].v;
if (vis[v]) continue;
ans-=calc(v,eg[i].w);
root=; tot=size[v];
getRoot(v,u);
solve(root);
}
}
int main()
{
scanf("%d%d",&n,&m);
init();
rep(i,,n-)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u+,v+,w);
add(v+,u+,w);
}
root=; tot=n;
getRoot(,);
solve(root);
cout<<ans<<endl;
}

codeforces716E (点分治)的更多相关文章

  1. [bzoj2152][聪聪和可可] (点分治+概率)

    Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...

  2. POJ 2965. The Pilots Brothers' refrigerator 枚举or爆搜or分治

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22286 ...

  3. [poj1741][tree] (树/点分治)

    Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...

  4. 【教程】简易CDQ分治教程&学习笔记

    前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦!       CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...

  5. BZOJ 3262 陌上花开 ——CDQ分治

    [题目分析] 多维问题,我们可以按照其中一维排序,然后把这一维抽象的改为时间. 然后剩下两维,就像简单题那样,排序一维,树状数组一维,按照时间分治即可. 挺有套路的一种算法. 时间的抽象很巧妙. 同种 ...

  6. BZOJ 1176 [Balkan2007]Mokia ——CDQ分治

    [题目分析] 同BZOJ2683,只需要提前处理s对结果的影响即可. CDQ的思路还是很清晰的. 排序解决一维, 分治时间, 树状数组解决一维. 复杂度是两个log [代码] #include < ...

  7. BZOJ 2683 简单题 ——CDQ分治

    [题目分析] 感觉CDQ分治和整体二分有着很本质的区别. 为什么还有许多人把他们放在一起,也许是因为代码很像吧. CDQ分治最重要的是加入了时间对答案的影响,x,y,t三个条件. 排序解决了x ,分治 ...

  8. HDU5977 Garden of Eden(树的点分治)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5977 Description When God made the first man, he ...

  9. Tsinsen A1493 城市规划(DP + CDQ分治 + NTT)

    题目 Source http://www.tsinsen.com/A1493 Description 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在 ...

随机推荐

  1. 读javascript高级程序设计17-在线检测,cookie,子cookie

    一.在线状态检测 开发离线应用时,往往在离线状态时把数据存在本地,而在联机状态时再把数据发送到服务器.html5提供了检测在线状态的方法:navigator.onLine和online/offline ...

  2. Fair Scheduler中的Delay Schedule分析

    延迟调度的主要目的是提高数据本地性(data locality),减少数据在网络中的传输.对于那些输入数据不在本地的MapTask,调度器将会延迟调度他们,而把slot分配给那些具备本地性的MapTa ...

  3. php翻页

    <?php$conn = mysql_connect("localhost","root","") or die("连接数据 ...

  4. POJ 2229 Sumsets

    Sumsets Time Limit: 2000MS   Memory Limit: 200000K Total Submissions: 11892   Accepted: 4782 Descrip ...

  5. 【转】Swift之 ? 和 !

    原文地址:http://joeyio.com/ios/2014/06/04/swift---/ Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值,也就是说变量不会 ...

  6. Eclipse里面Outline中图标的含义

    先说颜色:  绿色:public  黄色:protected  蓝色:no modifier  红色:private 再说形状:  实心:method  空心:variable  实心中间有字母C:c ...

  7. spring定时器

    本人小菜鸟一枚,今天在公司看到一段spring定时器配置,自己总结一下! <!-- 定义调用对象和调用对象的方法 --><bean id="jobtask9" c ...

  8. EF升级6.0数据库链接不上问题

    昨天搞了个mvc4  先从net4.0 升级4.5后 数据库连接不上了,  然后升级ef未最新的6.1  居然还报错 不到方法:“System.Data.Objects.ObjectContext S ...

  9. 使用开源DocX 生成Word

    工作中遇到这样一个需求,要求把选中的订单导出到一张Word中(要求不能使用Com组件) 要求实现图如下 下面是代码实现  先引用 DocX string tempName = Guid.NewGuid ...

  10. 百度前端技术学院2015JavaScript基础部分代码实现

    2. JavaScript数据类型及语言基础(一)    2.1 任务描述 创建一个JavaScript文件,比如util.js: 实践判断各种数据类型的方法,并在util.js中实现以下方法:  / ...