Luogu P5351 Ruri Loves Maschera
先ORZ\(Owen\)一发。感觉是个很套路的题,这里给一个蒟蒻的需要特判数据的伪\(n\log^2 n\)算法,真正的两只\(\log\)的还是去看标算吧(但这个好想好写跑不满啊)
首先这种树上路径统计的问题我们先套一个点分治上去就是了,然后求出分治中心连出去的每一条路径
我们还是套路地分成不同子树求解,如果我们对一条路径设一个二元组\((dep,val)\)表示到分治中心的深度以及路径上的最大值,那么就考虑怎么把一棵子树内的路径和其它子树的合并了
考虑如果只有一个端点限制怎么做,很容易想到它们的和取值都满足单调性
那么我们直接把两边都按\(dep\)排序,然后直接\(\text{two points}\)扫出一个端点的范围即可
接下来考虑两个端点怎么做,我们发现此时可以选的点形成了一个区间,既然这个区间两个端点都满足单调性,所以这个区间移动也是单调的
那么就很简单了,我们扫出每个点的合法区间之后考虑怎么统计答案
首先所有比它小的数最后的贡献都是它的权值,然后所有大于它的数的贡献即是它们本身
我们直接拿两个树状数组来维护,一个记录比它小的数的个数,另一个记录比它大的数的权值和,直接跟着指针一起添删点即可
很容易发现,这样的复杂度大部分消耗在排序上,如果每次暴力排序的话复杂度最坏会被卡到\(n^2\log^2 n\),但是很多时候一个点的度数没有那么多,所以跑起来非常快,大致比两个\(\log\)多一些常数吧
所以我们写完之后特判一下菊花图即可,这个更加简单,因为路径长度只有\(1/2\),暴力排序后枚举一下即可
CODE
#include<cstdio>
#include<cctype>
#include<algorithm>
#define RI int
#define CI const int&
#define Tp template <typename T>
using namespace std;
typedef long long LL;
const int N=100005,INF=1e9;
struct edge
{
int to,nxt,v;
}e[N<<1]; int n,head[N],rst[N],num,cnt,L,R,x,y,z; LL ans; bool flag;
class FileInputOutput
{
private:
static const int S=1<<21;
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,S,stdin),A==B)?EOF:*A++)
char Fin[S],*A,*B;
public:
Tp inline void read(T& x)
{
x=0; char ch; while (!isdigit(ch=tc()));
while (x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));
}
#undef tc
}F;
inline int min(CI a,CI b)
{
return a<b?a:b;
}
inline void addedge(CI x,CI y,CI z)
{
e[++cnt]=(edge){y,head[x],z}; head[x]=cnt;
e[++cnt]=(edge){x,head[y],z}; head[y]=cnt;
}
namespace Case1 //Point Division Solver
{
class Tree_Array
{
private:
int size[N]; LL sum[N]; bool vis[N];
public:
#define lowbit(x) x&-x
inline void add(CI x,CI y,CI opt,RI i=0)
{
for (i=x;i<=num;i+=lowbit(i)) size[i]+=opt;
for (i=x;i;i-=lowbit(i)) sum[i]+=opt*y;
}
inline int query_rk(RI x,int ret=0)
{
for (;x;x-=lowbit(x)) ret+=size[x]; return ret;
}
inline LL query_sum(RI x,LL ret=0)
{
for (;x<=num;x+=lowbit(x)) ret+=sum[x]; return ret;
}
#undef lowbit
}BIT;
#define to e[i].to
class Point_Division_Solver
{
private:
struct data
{
int dep,mxv;
friend inline bool operator < (const data& A,const data& B)
{
return A.dep<B.dep;
}
}s[N]; int size[N],tot,pl[N],pr[N]; bool vis[N];
inline int max(CI a,CI b)
{
return a>b?a:b;
}
inline void maxer(int& x,CI y)
{
if (y>x) x=y;
}
inline void DFS(CI now,CI fa,CI d,CI mx)
{
s[++tot]=(data){d,mx}; if (L<=d&&d<=R) ans+=rst[mx];
for (RI i=head[now];i;i=e[i].nxt)
if (to!=fa&&!vis[to]) DFS(to,now,d+1,max(mx,e[i].v));
}
public:
int mx[N],ots,rt;
inline void getrt(CI now,CI fa=1)
{
size[now]=1; mx[now]=0;
for (RI i=head[now];i;i=e[i].nxt) if (to!=fa&&!vis[to])
getrt(to,now),size[now]+=size[to],maxer(mx[now],size[to]);
if (maxer(mx[now],ots-size[now]),mx[now]<mx[rt]) rt=now;
}
inline void solve(CI now)
{
RI i,j; vis[now]=1; tot=0; int lst=0;
for (i=head[now];i;i=e[i].nxt) if (!vis[to])
{
DFS(to,now,1,e[i].v); sort(s+lst+2,s+tot+1); if (lst)
{
int p1=lst; for (j=lst+1;j<=tot;++j)
{
while (p1&&s[p1].dep+s[j].dep>R) --p1; pr[j]=p1;
}
int p2=1; for (j=tot;j>lst;--j)
{
while (p2<=lst&&s[p2].dep+s[j].dep<L) ++p2; pl[j]=p2;
}
p1=lst+1; p2=lst; for (j=lst+1;j<=tot;++j)
{
while (p1>pl[j]) --p1,BIT.add(s[p1].mxv,rst[s[p1].mxv],1);
while (p2>pr[j]) BIT.add(s[p2].mxv,rst[s[p2].mxv],-1),--p2;
ans+=1LL*BIT.query_rk(s[j].mxv)*rst[s[j].mxv]+BIT.query_sum(s[j].mxv+1);
}
for (j=p1;j<=p2;++j) BIT.add(s[j].mxv,rst[s[j].mxv],-1);
}
lst=tot; sort(s+1,s+lst+1);
}
for (i=head[now];i;i=e[i].nxt) if (!vis[to])
mx[rt=0]=INF,ots=size[to],getrt(to,now),solve(rt);
}
}PD;
#undef to
inline void solve(void)
{
sort(rst+1,rst+n); num=unique(rst+1,rst+n)-rst-1;
for (RI i=1;i<=cnt;++i) e[i].v=lower_bound(rst+1,rst+num+1,e[i].v)-rst;
PD.mx[PD.rt=0]=INF; PD.ots=n; PD.getrt(1); PD.solve(PD.rt);
}
};
namespace Case2 //Flower Graph Solver
{
inline void solve(void)
{
RI i; sort(rst+1,rst+n); if (L<=1&&1<=R)
for (i=1;i<n;++i) ans+=rst[i]; if (L<=2&&2<=R)
for (i=1;i<n;++i) ans+=1LL*rst[i]*(i-1);
}
};
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
RI i; for (F.read(n),F.read(L),F.read(R),flag=i=1;i<n;++i)
{
F.read(x); F.read(y); F.read(z);
addedge(x,y,z); rst[i]=z; if (min(x,y)!=1) flag=0;
}
if (flag) Case2::solve(); else Case1::solve();
return printf("%lld",ans<<1LL),0;
}
Luogu P5351 Ruri Loves Maschera的更多相关文章
- 【luogu P2397 yyy loves Maths VI (mode) 】 题解
题目链接:https://www.luogu.org/problemnew/show/P2397 卡空间. 对于众数出现次数 > n/2 我们考虑rand. 每次正确的概率为1/2,五个测试点, ...
- Luogu P3362 Cool loves shaxian 生成函数
题意: 定义f(i)=∑ k∣i k^d(i≤n),给出q个询问,每个询问询问区间[l,r]的f(i)的和. n<=1e7 d<=1e18 q<=5e4 可以发现f(i)是个积性函数 ...
- Luogu P2397 yyy loves Maths VI (mode)
题目传送门 虽然只是一道黄题,但还是学到了一点新知识-- 摩尔投票法 用\(O(1)\)的内存,\(O(n)\)的时间来找出一串长度为n的数中的众数,前提是众数出现的次数要大于\(n/2\) 方法很简 ...
- Luogu P3602 Koishi Loves Segments
传送门 题解 既然是选取区间,没说顺序 肯定先排遍序 都是套路 那么按什么排序呢??? 为了方便处理 我们把区间按左端点从小到大排序 把关键点也按从小到大排序 假设当扫到 \(i\) 点时,i 点之前 ...
- 2019年5~6月训练记录(更新ing)
前言 \(ZJOI\)正式结束了. 但期中考试只考了年级\(216\),退役既视感... 于是就被抓回去补文化课了. 下半个学期可能要以文化课为主了吧! 但周三.周日应该还是会正常参加训练的,但其他时 ...
- 『题解』Codeforces121A Lucky Sum
更好的阅读体验 Portal Portal1: Codeforces Portal2: Luogu Description Petya loves lucky numbers. Everybody k ...
- Luogu P5048 [Ynoi2019模拟赛]Yuno loves sqrt technology III 分块
这才是真正的$N\sqrt{N}$吧$qwq$ 记录每个数$vl$出现的位置$s[vl]$,和每个数$a[i]=vl$是第几个$vl$,记为$P[i]$,然后预处理出块$[i,j]$区间的答案$f[i ...
- bzoj2456 / P2397 yyy loves Maths VI (mode)
P2397 yyy loves Maths VI (mode) 神奇的摩尔投票法(大雾) 保证众数个数大于一半. 两两相消,剩下的那个必定是众数. 我们只要开2个变量,一个存个数,一个存值即可. (l ...
- 『题解』Codeforces446C DZY Loves Fibonacci Numbers
更好的阅读体验 Portal Portal1: Codeforces Portal2: Luogu Description In mathematical terms, the sequence \( ...
随机推荐
- 地理位置(navigation.geolocation)与本地存储(seessionStorage、localStorage)
一.地理位置( geolocation ): navigator.geolocation对象: 1.单次请求: //navigator.geolocation.getCurrentPosition( ...
- Matplotlib 在绘画bar时, 鼠标响应点击 bar 的消息
官方教程: http://urania.udea.edu.co/sitios/astronomia-2.0/pages/descargas.rs/files/descargasdt5vi/Cursos ...
- bzoj 3559: [Ctsc2014]图的分割【最小生成树+并查集】
读题两小时系列-- 在读懂题意之后,发现M(c)就是c这块最大权割边也就是的最小生成树的最大权边的权值,所以整个问题都可以在MST的过程中解决(M和c都是跟着并查集变的) 不过不是真的最小生成树,是合 ...
- [Xcode 实际操作]七、文件与数据-(17)解析JSON文档
目录:[Swift]Xcode实际操作 本文将演示如何解析JSON文档. 项目中已添加一份JSON文档:menu.json { "menu": { "id": ...
- FONT 字体颜色大全
用这句代码 替换 AmericanTypewriter-Bold字段就会有不同的字体样式 _typeLabel.font = [UIFont fontWithName:]; Font Family: ...
- CF #546div2D
题目本质:只有能做到一路过关斩将的勇者才能冒泡过来救出女主. 主要代码: ; int n, m, a[maxn], ans; vector<int> edge[maxn]; set< ...
- 自己写一个轻量的JqueryGrid组件
接触mvc不久,突然没有了viewstate和服务端控件处处都觉得不顺手,很多在webform时不必要考虑的问题都出现在眼前,这其中分页时查询条件保持的问题又是最让我头疼的事情,权衡再三,决定用aja ...
- Ubuntu-apt安装Jenkins
系统环境: Ubuntu 16.0.4 2CPU,8G 1.默认Ubuntu软件包里没有Jenkins 2.系统里添加存储密钥 wget -q -O - https://pkg.jenkins.io/ ...
- c#学习系列之静态类,静态构造函数,静态成员,静态方法(总之各种静态)
<1>静态类: 静态类与非静态类的重要区别在于静态类不能实例化,也就是说,不能使用 new 关键字创建静态类类型的变量.静态类最大的特点就是共享.在声明一个类时使用static关键字,具有 ...
- override和overload的小笔记
override是覆盖的意思,也就是我们的重写.可以重写覆盖父类的方法,然后实现接口的方法也可以叫做override. 几个要注意的点: 重写一定要用和被重写方法同样的方法名还有参数列表. 抛出的异常 ...