Pandaria

题解

很恶心的一道题。

首先问从点xxx开始走长度不超过www的边很容易让人想到Kruskal重构树。
每次在最小生成树中加入边时,我们相当于新建一个节点,连接我们两点所在的子树的树根,作为它们的父亲,将边权设为其点权。
由于加入的边的边权是递增的,我们查询的点的父亲的点权肯定也是递增的。
该点能走不超过www的边到达的节点,肯定是它点权不超过www的深度最小的父亲的整棵子树内的所有节点。
我们查询能走到的出现次数最多的颜色,相当于查询该子树内哪种颜色出现次数最多。

显然,我们可以按dfs序将所有叶子节点排成一个序列,一个点子树内的点对应的区间在该序列上肯定是连续的。
由于只有叶子是我们原先就存在的节点,是有颜色的,我们只需要将叶子排成序列。
那么该子树内出现次数最多的颜色,也就是区间众数。
区间众数显然有我们经典的O(nn)O\left(n\sqrt{n}\right)O(nn​)的分块做法 ,当然如果你会O(n)−O(1)O\left(n\right)-O\left(1\right)O(n)−O(1)的RMQRMQRMQ做法的也可以用,感觉跟四毛子算法有点像,但半群什么的我真的不会。
我们可以记录下每两个块之间出现次数最多的颜色是什么,显然这个颜色是可能成为众数的。
这个预处理是O(n2S)O\left(\frac{n^2}{S}\right)O(Sn2​),SSS即块长,这样我们就可以O(1)O(1)O(1)求出整块的众数。
而散块内每个点都是可能成为众数,我们可以对于它们每个数都查询一下就行了。
为了查询散块内点的出现次数,我们需要先预处理出整块内每种颜色的前缀和,每次查询的时候还得先更新一下散块内每种颜色的出现次数。
显然,散块内只会有SSS级别的颜色数,所以这块是O(S)O\left(S\right)O(S)的,而总共只会有nnn中颜色,整块的预处理也是O(n2S)O\left(\frac{n^2}{S}\right)O(Sn2​)。

总时间复杂度O(n2S+qS+mlog⁡m)⩾O(n2q+mlog⁡m)O\left(\frac{n^2}{S}+qS+m\log\,m\right)\geqslant O\left(\sqrt{n^2q}+m\log\,m\right)O(Sn2​+qS+mlogm)⩾O(n2q​+mlogm)。

源码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100005
#define MAXM 200005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long LL;
typedef unsigned long long uLL;
const int INF=0x3f3f3f3f;
const int inv2=499122177;
const int jzm=2333;
const int n1=400;
const int zero=10000;
const int orG=3,invG=332748118;
const double Pi=acos(-1.0);
const double eps=1e-5;
typedef pair<int,int> pii;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){_T f=1;x=0;char s=getchar();while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}x*=f;
}
template<typename _T>
void print(_T x){putchar('\n');while(x>9){putchar((x%10)|'0');x/=10;}putchar(x|'0');}
LL gcd(LL a,LL b){return !b?a:gcd(b,a%b);}
int add(int x,int y,int p){return x+y<p?x+y:x+y-p;}
void Add(int &x,int y,int p){x=add(x,y,p);}
int qkpow(int a,int s,int p){int t=1;while(s){if(s&1LL)t=1ll*a*t%p;a=1ll*a*a%p;s>>=1LL;}return t;}
const int M=MAXN/n1+5;
int T,n,m,q,head[MAXM],tot,fa[MAXM],idx,dfn[MAXM],rd[MAXM];
int f[MAXM][20],val[MAXM],col[MAXN],pre[MAXN];
int block[MAXN],L[M],R[M],mx[M][M],summ[M][MAXN],cnt[MAXN];
struct ming{int u,v,w;}s[MAXM];
bool cmp(ming x,ming y){return x.w<y.w;}
struct edge{int to,nxt;}e[MAXM<<1];
void addEdge(int u,int v){e[++tot]=(edge){v,head[u]};head[u]=tot;}
void makeSet(int x){for(int i=1;i<=x;i++)fa[i]=i;}
int findSet(int x){return fa[x]==x?x:fa[x]=findSet(fa[x]);}
void dosaka(int u,int fa){f[u][0]=fa;dfn[u]=idx;if(u<=n)pre[idx]=u,idx++;for(int i=1;i<19;i++)f[u][i]=f[f[u][i-1]][i-1];for(int i=head[u];i;i=e[i].nxt)if(e[i].to!=fa)dosaka(e[i].to,u);rd[u]=idx-1;
}
inline int ask(int l,int r,int c){return summ[r][c]-summ[l-1][c];}
signed main(){read(T);int tt=0;while(T--){read(n);read(m);makeSet(n);idx=n;int lans=0;for(int i=1;i<=n;i++)read(col[i]);for(int i=1;i<=m;i++)read(s[i].u),read(s[i].v),read(s[i].w);sort(s+1,s+m+1,cmp);val[0]=INF;for(int i=1;i<=m;i++){int u=s[i].u,v=s[i].v,w=s[i].w;if((u=findSet(u))==(v=findSet(v)))continue;fa[u]=fa[v]=fa[++idx]=idx;val[idx]=w;addEdge(idx,u);addEdge(idx,v);}int up=idx;idx=1;for(int i=up;i>0;i--)if(!dfn[i])dosaka(i,0);for(int i=1;i<=n;i++)block[i]=(i+n1-1)/n1;for(int i=1;i<=n;i++){if(!L[block[i]])L[block[i]]=i;R[block[i]]=i;}for(int i=1;i<=block[n];i++){for(int j=1;j<=n;j++)summ[i][j]=summ[i-1][j];for(int j=L[i];j<=R[i];j++)summ[i][col[pre[j]]]++;}for(int i=1;i<=block[n];i++)for(int j=i;j<=block[n];j++){mx[i][j]=mx[i][j-1];int maxx=ask(i,j,mx[i][j]);for(int k=L[j];k<=R[j];k++){int tmp=ask(i,j,col[pre[k]]);if(tmp>maxx||(tmp==maxx&&col[pre[k]]<mx[i][j]))mx[i][j]=col[pre[k]],maxx=tmp;}}printf("Case #%d:\n",++tt);read(q);for(int i=1;i<=q;i++){int x,w;read(x);read(w);x^=lans;w^=lans;for(int j=18;j>=0;j--)if(val[f[x][j]]<=w)x=f[x][j];int l=dfn[x],r=rd[x],res=0;const int al=block[l],ar=block[r];if(al==ar){for(int j=l;j<=r;j++){cnt[col[pre[j]]]++;if(cnt[col[pre[j]]]>cnt[res])res=col[pre[j]];else if(cnt[col[pre[j]]]==cnt[res]&&col[pre[j]]<res)res=col[pre[j]];}printf("%d\n",lans=res);for(int j=l;j<=r;j++)cnt[col[pre[j]]]=0;}else{res=mx[al+1][ar-1];for(int j=l;j<=R[al];j++){int t=col[pre[j]];cnt[t]++;int tmp1=cnt[t]+ask(al+1,ar-1,t);int tmp2=cnt[res]+ask(al+1,ar-1,res);if(tmp1>tmp2||(tmp1==tmp2&&t<res))res=t;}for(int j=L[ar];j<=r;j++){int t=col[pre[j]];cnt[t]++;int tmp1=cnt[t]+ask(al+1,ar-1,t);int tmp2=cnt[res]+ask(al+1,ar-1,res);if(tmp1>tmp2||(tmp1==tmp2&&t<res))res=t;}printf("%d\n",lans=res);for(int j=l;j<=R[al];j++)cnt[col[pre[j]]]=0;for(int j=L[ar];j<=r;j++)cnt[col[pre[j]]]=0;}}for(int i=1;i<=up;i++)for(int j=0;j<19;j++)f[i][j]=0;for(int i=1;i<=up;i++)val[i]=head[i]=dfn[i]=pre[i]=rd[i]=0;tot=idx=0;for(int i=1;i<=block[n];i++)for(int j=1;j<=n;j++)summ[i][j]=0;}return 0;
}

谢谢!!!

[2016-2017 ACM-ICPC CHINA-Final G]Pandaria相关推荐

  1. ACM ICPC China final G Pandaria

    目录 ACM ICPC China final G Pandaria ACM ICPC China final G Pandaria 题意:给一张\(n\)个点\(m\)条边的无向图,\(c[i]\) ...

  2. 2017 ACM ICPC Asia Regional - Daejeon

    2017 ACM ICPC Asia Regional - Daejeon Problem A Broadcast Stations 题目描述:给出一棵树,每一个点有一个辐射距离\(p_i\)(待确定 ...

  3. C - Mr. Panda and Strips Gym - 101194C(思维//尺取//2016 icpc china final)

    VJ地址 题意:选择一段or两段连续的区间,合成一段序列,使得选择的序列中没有相同的数字,求序列最长的长度 思路:由于是区间内不能有相同的数字,所以考虑用尺取,可以2*n的时间枚举第一段的长度,然后剩 ...

  4. 2017 ACM/ICPC 南宁赛区小结 By JSB @ Reconquista

    Statistics TYPE: Onsite Contest NAME: 2017 - ICPC - Asia Nanning PLAT: pc^2 TIME: 2017/11/26 09:00-1 ...

  5. 2017 ACM ICPC Asia Shenyang Regional Contest 题解(10 / 13)【每日亿题2 / 16】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 A.(2017 ICPC shenyang I)Little Boxes B.(2017 ICP ...

  6. 2017 ACM/ICPC 北京赛区小结 By jsb @Reconquista

    Statistics TYPE: Onsite Contest NAME: 2017 - ICPC - Asia Beijing PLAT: hihoCoder TIME: 2017/11/19 09 ...

  7. 2017 ACM/ICPC(西安)赛后总结

    早上8:00的高铁,所以不得不6点前起床,向火车站赶--到达西安后已经是中午,西工大距离西安北站大概3小时车程的距离,只好先解决午饭再赶路了--下午3.30的热身赛,一行人在3.35左右赶到了赛场,坐 ...

  8. [Contest]2017 ACM/ICPC Asia Regional Shenyang Online(01 03 07 09 10 11待补)

    1001 string string string 题意 给定一个字符串$s$,求其中出现$k$次的子串的个数. 题解 后缀自动机. 代码 1002 cable cable cable 题意 给定$M ...

  9. 2017 ACM ICPC Asia Regional - Daejeon Programming Constest

    A: Broadcast Stations 题目大意 给定一棵树,选一些节点iii,赋予P(i)" role="presentation">P(i)P(i)P(i) ...

  10. 2017 ACM/ICPC Asia Regional Shenyang Online array

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=6197 题目大意:给出一个序列,删去k个元素是否能构成不上升序列或不下降子序列 (呃,先凑个数吧 二分+ ...

最新文章

  1. open*** 启动报错
  2. 3万字细品数据倾斜(建议收藏)
  3. oracle调度不见了,Oracle作业job 没有自动调度起来
  4. SQL Server 数据库构架
  5. Simulink之电网电压换流式有源逆变电路
  6. UiPath实践经验总结(二)
  7. [转]notepad++各种插件
  8. Blazor 服务器上带有 EF Core 的 Azure Cosmos DB
  9. SwiftTour基础学习(五)控制流
  10. Leetcode431.将N叉树编码为二叉树(golang)
  11. 教师国培计算机计划,教师国培计划大全
  12. KEIL STC 仿真
  13. 检测相关问题面试准备
  14. 网页设计配色应用实例剖析——蓝色系
  15. 两数求和(C语言超简单解法)
  16. 图形学基础知识:走样和反走样,频域和滤波
  17. 学数学,要“直觉”还是要“严谨”?
  18. Java 选择视频文件对话窗口
  19. 郭店楚简——原简整理,文物出版社
  20. Redis解决高并发(秒杀抢红包)

热门文章

  1. Pushmall共享电商营销推广平台2023年6月升级进度
  2. Collections的copy()方法和ArrayList的大小问题
  3. 丫丫头-玲珑塔设计教程
  4. 第五节 利用Ogre 2.3实现雨,雪,爆炸,飞机喷气尾焰等粒子效果
  5. 棋魂71-75 + 回忆篇 + 通向北斗之路
  6. 杰理AC692N系列增加编码器通过AD检测方式
  7. 网赚那些事儿——谈谈我如何月入1500
  8. 2018会考计算机成绩查询,2018会考成绩在哪里查询 会考成绩有用吗
  9. 【Python】python通配符,使用通配符进行字符串匹配
  10. PLC可以连接哪些工业设备实现远距离无线通讯?工业网关可以吗?