(咕咕咕咕咕)

(先挖坑)

填坑

题意:有一颗树,树上每个点有一个颜色,定义合法的路径为一条路径上所有点颜色都不相同,求有多少合法路径

观察题面,题中有一个条件为每种颜色的点不超过20个,于是想到一种特殊的做法,枚举每种颜色中的点对,对于一个点对u,v,如果u是v的祖宗,则一个在v的子树里的点和一个不在与v所在相同的u的子树里的点是不合法的路径,如果u,v不是祖孙关系,则一个在u的子树与一个在v的子树里的点的路径是不合法的。我们将这些不合法的点对的起点与终点看作二维平面的x和y,将不合法的点对看作一个个矩形,因为这些点对都是在子树中的,所以先处理下dfs序就可以了,然后跑一个扫描线,剪掉不合法的就ok了(我扫描线不会写真是菜死了),在扫描线的时候应该要注意,起点和终点反过来计算重复的问题,我采用的方法是只考虑dfs序中起点大于终点的情况。

代码如下

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int N=1e5+5;
struct tree
{int l,r,sum,lz,LZ;
}t[N*4];
struct edge
{int to,next;
}e[N*2];
struct name
{int l,r,q;name(){}name(int a,int b,int c){l=a,r=b,q=c;}friend inline bool operator <(const name &a,const name &b){return a.q>b.q;}
};
int head[N],ecnt;
int n,c[N];
ll ans;
vector<int>vt[N];
vector<name>v[N];
void add(int u,int v)
{e[++ecnt].to=v;e[ecnt].next=head[u];head[u]=ecnt;
}
int ti,dfn[N],pos[N],ed[N];
void dfs(int u)
{dfn[u]=++ti;pos[ti]=u;for(int i=head[u];i;i=e[i].next) if(!dfn[e[i].to]) dfs(e[i].to);ed[u]=ti;
}
void build(int p,int l,int r)
{t[p].l=l;t[p].r=r;t[p].sum=0;t[p].lz=t[p].LZ=0;if(l==r) return (void)(t[p].sum=1);int mid=l+r>>1;build(p<<1,l,mid);build(p<<1|1,mid+1,r);t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
}
//只考虑dfs序起点大于终点的情况
void adds(int xs,int xe,int ys,int ye)
{if(xs>xe||ys>ye) return ; if(xs>ys) swap(xs,ys),swap(xe,ye);v[xs].push_back(name(ys,ye,-1));v[xe+1].push_back(name(ys,ye,1));//printf("%d-%d//%d-%d\n",xs,xe,ys,ye);
}
void work(int u,int v)
{if(dfn[u]>dfn[v]) swap(u,v);if(dfn[v]>dfn[u] && dfn[v]<=ed[u]){for(int i=head[u],x;i;i=e[i].next){x=e[i].to;if(dfn[v]>=dfn[x] && dfn[v]<=ed[x]){adds(1,dfn[x]-1,dfn[v],ed[v]);adds(ed[x]+1,n,dfn[v],ed[v]);}}}else{adds(dfn[u],ed[u],dfn[v],ed[v]);}
}
void push_down(int p)
{if(t[p].l==t[p].r) return ;if(t[p].lz==0) return ;t[p<<1].lz+=t[p].lz;t[p<<1].LZ+=t[p].lz;if(t[p<<1].LZ<0) t[p<<1].sum=0;else t[p<<1].sum=t[p<<1].r-t[p<<1].l+1;t[p<<1|1].lz+=t[p].lz;t[p<<1|1].LZ+=t[p].lz;if(t[p<<1|1].LZ<0) t[p<<1|1].sum=0;else t[p<<1|1].sum=t[p<<1|1].r-t[p<<1|1].l+1;t[p].lz=0;
}
void modify(int p,int l,int r,int w)
{if(t[p].l==l &&t[p].r==r){t[p].lz+=w;if(t[p].lz<0) t[p].sum=0;else if(l==r) t[p].sum=1;else t[p].sum=t[p<<1].sum+t[p<<1|1].sum;return ;}//  push_down(p);int mid=t[p].l+t[p].r>>1;if(mid>=r) modify(p<<1,l,r,w);else if(l>mid) modify(p<<1|1,l,r,w);else modify(p<<1,l,mid,w),modify(p<<1|1,mid+1,r,w);if(t[p].lz==0)t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
}
int query(int p,int l,int r)
{if(t[p].l==l &&t[p].r==r) return /*printf("(%d,%d,%d)",l,r,t[p].sum),*/t[p].sum;int mid=t[p].l+t[p].r>>1;if(mid>=r) return query(p<<1,l,r);if(l>mid) return query(p<<1|1,l,r);return query(p<<1,l,mid)+query(p<<1|1,mid+1,r);
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&c[i]),vt[c[i]].push_back(i);for(int i=1,u,v;i<n;i++) scanf("%d%d",&u,&v),add(u,v),add(v,u);dfs(1);//  for(int i=1;i<=n;i++) printf("%d(%d)\n",i,dfn[i]);for(int i=1,sz;i<=n;i++){sz=vt[i].size();for(int j=0;j<sz;j++)for(int k=j+1;k<sz;k++)work(vt[i][j],vt[i][k]);}build(1,1,n);for(int i=1,sz;i<=n;i++){sz=v[i].size();sort(v[i].begin(),v[i].end());for(int j=0;j<sz;j++){name u=v[i][j];modify(1,u.l,u.r,u.q);//      printf("%d:%d-%d(%d)\n",i,u.l,u.r,u.q);
    }int FAQ=query(1,i,n);//   printf("QUERY%d=%d\n",i,FAQ);ans+=FAQ;}printf("%lld\n",ans);return 0;
}
// 3 1 2 3 1 2 1 3
// 5 1 1 2 3 3 1 2 1 3 2 4 2 5

转载于:https://www.cnblogs.com/pigba/p/8870828.html

LOJ6276 果树相关推荐

  1. Android手机远程控制手机

    1,先找两台Android手机,其中,(被控端的Android手机需要root权限) 2,控制端安装(向日葵远程控制   APP),被控制端安装(向日葵客户端) 3,不管控制端还是被控制端,都要求(必 ...

  2. JZOJ 5678. 【GDOI2018Day2模拟4.21】果树

    Description NiroBC 姐姐是个活泼的少女,她十分喜欢爬树,而她家门口正好有一棵果树,正好满足了她爬树的需求. 这颗果树有N个节点,节点标号 1-N.每个节点长着一个果子,第i个节点上的 ...

  3. 澄清烟台苹果果袋用药与果树种植

    作为烟台红富士的主产区的栖霞和招远,年产苹果十几亿公斤. 记者调查,一种小作坊生产,无任何标志的药袋被当地果农大量使用.这种药袋将包裹幼果直到成熟,白色药末直接与苹果接触.对于所用药物,药袋生产商和销 ...

  4. [10] JMeter-察看结果树,你知道都有哪些功能吗?

     0  前言 一说起两大压测工作Jmeter和LoadRunner的区别,可能很多人会说Jmeter的图表分析结果功能很差,LoadRunner在这方面则很强大. 我有很长一段时间也是这样认为,甚至还 ...

  5. jmeter学习指南之察看结果树,你知道都有哪些功能吗

    0 前言 一说起两大压测工作Jmeter和LoadRunner的区别,可能很多人会说Jmeter的图表分析结果功能很差,LoadRunner在这方面则很强大. 我有很长一段时间也是这样认为,甚至还经常 ...

  6. JMeter之察看结果树

    1.添加"察看结果树" 线程组---右键添加---监听器---察看结果树 在同一线程组下,可查看所有的请求结果 2.察看结果树的组成 2.1取样器结果 包含:线程组名称.开始时间. ...

  7. 天猫年货节“种果树、收水果”破除你的“水果焦虑”

    文|曾响铃 来源|科技向令说(xiangling0815) 元旦已过,眼看农历新年马上来临,又到了一年一度"囤货"的季节.有一类产品的"热度"从2019年春节期 ...

  8. 魔坊APP项目-25-种植园,植物的状态改动、当果树种植以后在celery的异步任务中调整浇水的状态、客户端通过倒计时判断时间,显示浇水道具

    种植园 植物的状态改动 一.当果树种植以后在celery的异步任务中调整浇水的状态 在进行果树种植的时候, 在服务端设置当前果树到等待浇水的redis变量中.通过celery不断进行周期任务的处理, ...

  9. Jmeter使用教程 压力测试(1)--线程组、HTTP请求、察看结果树

    线程组/Thread Group 线程数可理解为用户数. Ramp-up时间可理解为所有线程(用户)在该时间段内将请求发送完. 循环次数就是将整个线程循环发送的次数.若勾选"永远" ...

最新文章

  1. 常用的 css 样式 记录
  2. C#中的DateTime:本周,本月,今年,本周
  3. Http协议Get方式获取图片
  4. 前端学习(1775):前端调试之session storage原理和查看
  5. kali linux工具pyrit,在Kali Linux上安装cuda、pyritcuda以及optimus -电脑资料
  6. 人工智能诗歌写作平台_人工智能教作文,只写出二类文,人类语文老师稳赢
  7. BadgerDAO锁仓量超过9亿美元
  8. Android:日常学习笔记(8)———开发微信聊天界面
  9. QT使用ODBC连接MySQL
  10. 进入微信公众平台自动跳转到小程序界面,而不是微信公众号界面。
  11. DCMI接口之OV2640摄像头
  12. 计算机网络之无线与移动网络-蜂窝网络
  13. QQ计数器统计器使用教程
  14. 简述python 的模块的分析
  15. jmeter学习指南之生成html性能结果报告(篇幅较长谨慎阅读)
  16. 2.07 CISC与RISC
  17. [Python爬虫] 一、爬虫原理之HTTP和HTTPS的请求与响应
  18. 潦草字体在线识别_连笔字在线生成器
  19. 查看linux 系统 服务器型号
  20. 【AlgorithmTraining】08:Leetcode(上)

热门文章

  1. c++成员函数的调用——常成员函数
  2. 字节序(Byte Oder)
  3. java 异步请求completablefuture
  4. java-opencv剪辑图片
  5. jieba源码学习------TF-IDF方法 计算词权重
  6. 常见的机器学习分类模型
  7. Emoji For C++
  8. vue父组件调用子组件方法,失效解决方案
  9. Python入门到实践(第二版)作业 Part.2
  10. Linux下安全审计audit 系统审计 记录root操作