P3241 [HNOI2015]开店

题目描述

风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学。最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱。

这样的想法当然非常好啦,但是她们也发现她们面临着一个问题,那就是店开在哪里,面向什么样的人群。很神奇的是,幻想乡的地图是一个树形结构,幻想乡一共有 \(n\)个地方,编号为 \(1\) 到 \(n\) 被\(n-1\) 条带权的边连接起来。每个地方都住着一个妖怪,其中第 \(i\) 个地方的妖怪年龄是 \(x_i\) 。

妖怪都是些比较喜欢安静的家伙,所以它们并不希望和很多妖怪相邻。所以这个树所有顶点的度数都小于或等于 \(3\)。妖怪和人一样,兴趣点随着年龄的变化自然就会变化,比如我们的\(18\) 岁少女幽香和八云紫就比较喜欢可爱的东西。幽香通过研究发现,基本上妖怪的兴趣只跟年龄有关,所以幽香打算选择一个地方\(u\) (\(u\) 为编号),然后在\(u\)开一家面向年龄在 \(L\) 到 \(R\) 之间(即年龄大于等于 \(L\) 小于等于 \(R\) )的妖怪的店。

也有可能 \(u\) 这个地方离这些妖怪比较远,于是幽香就想要知道所有年龄在 \(L\) 到 \(R\) 之间的妖怪,到点 \(u\) 的距离的和是多少(妖怪到 \(u\) 的距离是该妖怪所在地方到 \(u\) 的路径上的边的权之和),幽香把这个称为这个开店方案的方便值。

幽香她们还没有决定要把店开在哪里,八云紫倒是准备了很多方案,于是幽香想要知道,对于每个方案,方便值是多少呢。

输入输出格式

输入格式:

第一行三个用空格分开的数 \(n,Q\) 和 \(A\) ,表示树的大小、开店的方案个数和妖怪的年龄上限。

第二行 \(n\) 个用空格分开的数\(x_1,x_2,\ldots,x_n;x_i\) 表示第 \(i\) 个地点妖怪的年龄,满足\(0\le x_i\lt A\) 。(年龄是可以为\(0\)的,例如刚出生的妖怪的年龄为\(0\) 。)

接下来 \(n-1\) 行,每行三个用空格分开的数 \(a\) 、\(b\) 、\(c\) ,表示树上的顶点 \(a\) 和 \(b\) 之间有一条权为\(c(1\le c\le1000)\)的边,\(a\) 和 \(b\) 是顶点编号。

接下来 \(Q\) 行,每行三个用空格分开的数\(u,a,b\) 。

对于这 \(Q\) 行的每一行,用 \(a,b,A\) 计算出 \(L\) 和 \(R\),表示询问在地方 \(u\) 开店,面向妖怪的年龄区间为\([L,R]\) 的方案的方便值是多少“。

对于其中第 \(1\) 行,\(L\) 和 \(R\) 的计算方法为:\(L=\min(a \% A,b \% A),R=\max(a \% A,b \%A)\) 。

对于第 \(2\) 到第 \(Q\) 行,假设前一行得到的方便值为\(ans\) ,那么当前行的 \(L\) 和 \(R\) 计算方法为: \(L=\min((a+ans) \% A,(b+ans) \% A),R=\max((a+ans) \% A, (b+ans)\%A)\)

输出格式:

对于每个方案,输出一行表示方便值。

说明

满足\(n\le1.5\times10^5,Q\le2\times10^5\) 。对于所有数据,满足 \(A\le10^9\)


动态点分=sb码农题+sb卡常题,以上...

要相信同样是两个\(\log\)的算法,有人是\(2s\),有人是\(30s\)

先把点分树弄出来,然后对每个点维护自己在点分树上的子树的每个点到点分树父亲的距离和,最开始我拿的线段树,因为要按年龄划分。

然后预处理是\(O(n\log^2n)\),查询是\(O(\log^2n)\)的

预处理按照点分治那样处理就可以了。

查询暴力向上跳,每次统计一下分治树外的答案+分治树外满足要求的点的个数乘上路径长度。

然后\(ST\)表的一个数组开小了,检查了快\(2h...\),然后卡常也卡不动,本地开\(10s\)才能勉强跑过去。注意这里年龄要先离散化,不然线段树开不下。

考虑没有查询可以直接前缀和,统计的时候拿\(vector\)存一下前缀和然后差分进行询问。询问的时候需要二分一下但是常数就小很多了。

然后咕咕不吸氧还是过不去...


Code:

// luogu-judger-enable-o2
#include <cstdio>
#include <vector>
#include <cctype>
#include <algorithm>
#define ll long long
const int N=150010;
using std::min;
using std::max;
int head[N],to[N<<1],Next[N<<1],edge[N<<1],cnt;
void add(int u,int v,int w)
{to[++cnt]=v,Next[cnt]=head[u],edge[cnt]=w,head[u]=cnt;
}
char c;int xx;
int read()
{c=getchar();xx=0;while(!isdigit(c)) c=getchar();while(isdigit(c)) {xx=xx*10+c-'0';c=getchar();}return xx;
}
namespace RMQLCA
{int dfn[N],st[N<<1][20],dep[N],Log[N<<1],dfs_clock;ll dis[N];void dfs(int now,int fa){dep[now]=dep[fa]+1;st[dfn[now]=++dfs_clock][0]=now;for(int v,i=head[now];i;i=Next[i])if((v=to[i])!=fa)dis[v]=dis[now]+edge[i],dfs(v,now),st[++dfs_clock][0]=now;}void init(){dfs(1,0);for(int i=2;i<=dfs_clock;i++) Log[i]=Log[i>>1]+1;for(int j=1;j<=19;j++){for(int x,y,i=1;i<=dfs_clock-(1<<j)+1;i++){x=st[i][j-1],y=st[i+(1<<j-1)][j-1];st[i][j]=dep[x]<dep[y]?x:y;}}}ll getdis(int x,int y){ll ret=dis[x]+dis[y];x=dfn[x],y=dfn[y];if(x>y) std::swap(x,y);int d=Log[y+1-x];x=st[x][d],y=st[y-(1<<d)+1][d];return ret-(dis[dep[x]<dep[y]?x:y]<<1);}
}
struct node
{int age,ct;ll f;bool friend operator <(node n1,node n2){return n1.age<n2.age;}
};
std::vector <node> sum[N];
std::vector <node>::iterator it;
ll su1=0,su2=0;
void query0(int now,int R)
{it=std::upper_bound(sum[now].begin(),sum[now].end(),(node){R,0,0});if(it!=sum[now].begin())it--,su1=it->f,su2=it->ct;elsesu1=su2=0;
}
int mi,rt,si,siz[N],del[N],par[N];
int n,q,m,poi[N],b[N];ll maxn;
void dfs1(int now,int fa)
{siz[now]=1;int mx=0;for(int v,i=head[now];i;i=Next[i])if(!del[v=to[i]]&&v!=fa)dfs1(v,now),siz[now]+=siz[v],mx=mx>siz[v]?mx:siz[v];mx=mx>si-siz[now]?mx:si-siz[now];if(mi>mx) mi=mx,rt=now;
}
void dfs2(int now,int fa,int w,ll dis)
{sum[w].push_back((node){poi[now],0,dis});for(int v,i=head[now];i;i=Next[i])if(!del[v=to[i]]&&v!=fa)dfs2(v,now,w,dis+edge[i]);
}
std::vector <int> Edge[N];
void deal(int now)
{std::sort(sum[now].begin(),sum[now].end());sum[now][0].ct=1;for(int i=1;i<sum[now].size();i++)sum[now][i].f+=sum[now][i-1].f,sum[now][i].ct=i+1;
}
void divide(int now)
{del[now]=1;for(int w,v,i=head[now];i;i=Next[i]){if(!del[w=to[i]]){mi=N,si=siz[w],dfs1(w,0);dfs2(w,0,v=rt,edge[i]);deal(v);par[v]=now,Edge[now].push_back(v);divide(v);}}
}
void getsum(int now,int v,int R,ll &ret1,ll &ret2)
{ret1=ret2=0;for(int w,i=0;i<Edge[now].size();i++)if((w=Edge[now][i])!=v)su1=su2=0,query0(w,R),ret1+=su1,ret2+=su2;ret2+=poi[now]<=R;
}
ll query(int now,int R)
{int las=now;ll ret1,ret2;getsum(now,0,R,ret1,ret2);ll ret=ret1;while(par[now]){getsum(par[now],now,R,ret1,ret2);ret+=ret1;ret+=ret2*RMQLCA::getdis(las,par[now]);now=par[now];}return ret;
}
int main()
{//freopen("data.in","r",stdin);//freopen("dew.out","w",stdout);n=read(),q=read(),maxn=read();for(int i=1;i<=n;i++) poi[i]=read();for(int u,v,w,i=1;i<n;i++){u=read(),v=read(),w=read();add(u,v,w),add(v,u,w);}RMQLCA::init();mi=N,si=n;dfs1(1,0),divide(rt);ll lastans=0;for(int u,l,r,i=1;i<=q;i++){u=read(),l=read(),r=read();l=(l+lastans)%maxn,r=(r+lastans)%maxn;if(l>r) std::swap(l,r);printf("%lld\n",lastans=(query(u,r)-query(u,l-1)));}return 0;
}

2018.12.6

转载于:https://www.cnblogs.com/butterflydew/p/10075516.html

洛谷 P3241 [HNOI2015]开店 解题报告相关推荐

  1. 洛谷1056 排座椅 解题报告

    洛谷1056 排座椅 本题地址: http://www.luogu.org/problem/show?pid=1056 题目描述 上课的时候总会有一些同学和前后左右的人交头接耳,这是令小学班主任十分头 ...

  2. 洛谷1067 多项式输出 解题报告

    洛谷1067 多项式输出 本题地址: http://www.luogu.org/problem/show?pid=1067 题目描述 一元 n 次多项式可用如下的表达式表示: 其中,aixi称为 i ...

  3. 洛谷 P4475 巧克力王国 解题报告

    P4475 巧克力王国 题目描述 巧克力王国里的巧克力都是由牛奶和可可做成的.但是并不是每一块巧克力都受王国人民的欢迎,因为大家都不喜欢过于甜的巧克力. 对于每一块巧克力,我们设 \(x\) 和 \( ...

  4. 洛谷 P4706 取石子 解题报告

    P4706 取石子 题目描述 现在 Yopilla 和 yww 要开始玩游戏! 他们在一条直线上标记了 \(n\) 个点,从左往右依次标号为 \(1, 2, ..., n\) .然后在每个点上放置一些 ...

  5. 洛谷 P1309 瑞士轮 解题报告

    P1309 瑞士轮 题目背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平,偶然性较低 ...

  6. 洛谷 P2184 贪婪大陆 解题报告

    P2184 贪婪大陆 题目背景 面对蚂蚁们的疯狂进攻,小\(FF\)的\(Tower\) \(defence\)宣告失败--人类被蚂蚁们逼到了\(Greed\) \(Island\)上的一个海湾.现在 ...

  7. 洛谷 P1136 迎接仪式 解题报告

    P1136 迎接仪式 题目描述 LHX教主要来X市指导OI学习工作了.为了迎接教主,在一条道路旁,一群Orz教主er穿着文化衫站在道路两旁迎接教主,每件文化衫上都印着大字.一旁的Orzer依次摆出&q ...

  8. 洛谷 P2596 [ZJOI2006]书架 解题报告

    P2596 [ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书, ...

  9. 洛谷 P3975 [TJOI2015]弦论 解题报告

    P3975 [TJOI2015]弦论 题目描述 为了提高智商,ZJY开始学习弦论.这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为\(n\)的字符串,求 ...

最新文章

  1. activity 启动模式_腾讯大牛:你根本不懂Activity!
  2. mysql的默认sid_默认实例(SID)已经设置,空实例默认连接时却连接不上?
  3. Matlab稀疏矩阵
  4. 在一个JS文件中包含中文字符串,通过innerHTML输出后中文乱码?
  5. php imap配置,php中的自定义IMAP命令
  6. GIT更新一其中一个提交版本
  7. pytorch固定BN层参数
  8. 苹果CMS采集方法支持文章资源采集
  9. 励志,一年绝境翻盘,大厂的逆袭之路
  10. 手把手教你制作一块Linux开发板(基于Planck-pi)
  11. 用HBuilderX代替微信开发者工具
  12. 图片轮播——Swiper实例
  13. 《优柔有情人》读后感6000字
  14. qt websocket android,QT使用websocket进行长连接
  15. VSCode 修改系统界面和编辑面板字体大小
  16. 小红书KOL营销策略,先搞清楚小红书kol分类有哪些
  17. 【英语】及物动词和不及物动词的区别vt、vi
  18. Java8.0 新特性二之Stream
  19. 关于AES:加密方式,让你的APK无懈可击,android性能优化和内存优化面试
  20. 五线谱基础教程视频乐理基础

热门文章

  1. 重生之——python与我不得不说的故事
  2. CNC加工中心常用的几种螺纹加工方法!
  3. 时间管理之背上的猴子
  4. Springboot毕设项目安易网上商品交易系统6aygw(java+VUE+Mybatis+Maven+Mysql)
  5. html解析图片url,并用继承Thread类的多线程下载
  6. mysql实训5答案_MySQL 实训篇 - osc_mi06gsf5的个人空间 - OSCHINA - 中文开源技术交流社区...
  7. 什么是计算机时间?程序员必看的时间知识!
  8. Android 后台实现录像,无页面息屏状态下后台录像
  9. 换新手机想要旧手机的聊天记录和一些东西的方法(本人两款都是小米系列)
  10. 使用do-while循环结构实现:计算1~50中的倍数的数值之和并输出