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. 油猴 greasemonkey 背景音乐 火狐 chrome 背景音乐

    火狐,chrome背景音乐 http://www.w3school.com.cn/tags/tag_audio.asp js插入背景音乐,猴油脚本使用 var audio = document.cre ...

  2. PHP global 关键字

    global关键字用于在函数内部访问全局变量. <?php $x = 5; $y = 10; function myTest(){ global $x,$y; $x = $x+$y; } myT ...

  3. php file_get_contents() 用法

    php 需要访问某个网页 <?php $fh= file_get_contents('http://www.baidu.com/'); echo $fh; ?> 知识扩充 file_get ...

  4. 个人介绍和Github使用流程

    我叫石莉静,来自网络工程143班,学号1413042067 我的兴趣爱好有看电影.动漫,听音乐,摄影,寻找美食等等. 个人编程能力:非常真诚的说,我的编程能力蛮差的,用C++写过一共写过...(很少很 ...

  5. 定时器springMVC

  6. js 判断是什么类型浏览器

    //  firefoxif ( window.sidebar && "object" == typeof( window.sidebar ) && ...

  7. guava学习--AsyncFunction

    AsyncFuntion接口与之前学习吃的使用Function和Functions进行对象转换有很密切的联系,AsyncFuction接口是Function接口的异步表现,AsyncFuction和F ...

  8. Web导出EXCEL

    前台(客户端)导出EXCEL: 单纯的JS能够导出Excel的,一般都需要调用客户端所安装的Office Excel组件(COM接口)来完成这个工作. http://www.stepday.com/t ...

  9. web.config连接字符串的一些总结

    阅读目录: DS01:数据库连接字符串的两种写法 DS02:数据库连接字符串的内容 DS01:数据库连接字符串的两种写法 1.连接字符串的两种写法: <configuration>   & ...

  10. regexxx

    var test={ msg:{ "name":"name","value":"value" }}var str=JSO ...