我们先考虑如何比较两两的字符串

我们可以用线段树来维护哈希值 在线段树上根据二分的性质来做即可

又考虑到 每颗线段树是在之前的某颗基础上只修改了一个节点 那显然就想到了主席树

另外说说如何pushup 我们考虑这样一个字符串 abcdefg

假设当前节点左儿子是abc 右儿子是defg

由于我们的哈希值用的是unsigned long long 自然溢出大法 也就是说abc的哈希值是a(base^1)+b(base^2)+c(base^3),而defg的哈希值是d(base^1)+...

因此只需要给cefg乘上一个base^3就好了

代码也很好写

#include<bits/stdc++.h>
#define N 100005
#define M 100005
#define ull unsigned long long
const int base=31;
using namespace std;
int n,m,tot,len[N],sum[N],p[N],lc[N],rc[N],rt[N];
ull pw[M];
char s[N];
void build(int &now,int l,int r)
{now=++tot;  len[now]=r-l+1;if(l==r){sum[now]=s[l];return;}int m=(l+r)>>1;build(lc[now],l,m);build(rc[now],m+1,r);sum[now]=sum[lc[now]]+sum[rc[now]]*pw[len[lc[now]]];
}
inline void copy(int &x,int y)
{x=++tot;lc[x]=lc[y];    rc[x]=rc[y];    len[x]=len[y];  sum[x]=sum[y];
}
inline void insert(int x,int &y,int l,int r,int p,int v)
{copy(y,x);if(l==r)    //把x复制一份 给y {sum[y]=v;return;}int m=(l+r)>>1;if(p<=m)    insert(lc[x],lc[y],l,m,p,v);else insert(rc[x],rc[y],m+1,r,p,v);sum[y]=sum[lc[y]]+sum[rc[y]]*pw[len[lc[y]]];
}
inline int cmp(int x,int y,int l,int r)
{if(l==r){if(sum[x]<sum[y])   return -1;else return 1;}int m=(l+r)>>1;if(sum[lc[x]]!=sum[lc[y]])  return cmp(lc[x],lc[y],l,m);else return cmp(rc[x],rc[y],m+1,r);
}
inline bool comp(const int &a,const int &b)
{if(sum[rt[a]]==sum[rt[b]])  return a<b;return cmp(rt[a],rt[b],1,m)<0;
}
int main()
{cin>>n>>m;scanf("%s",s+1);pw[0]=1;for(int i=1;i<=m;i++)   pw[i]=pw[i-1]*base;build(rt[1],1,m);for(int i=2;i<=n;i++){int who,pos;cin>>who>>pos;scanf("%s",s+1);insert(rt[who],rt[i],1,m,pos,s[1]); //把以i为根的线段树 接到被膜拜的人身上 }for(int i=1;i<=n;i++)   p[i]=i;sort(p+1,p+n+1,comp);for(int i=1;i<=n;i++)   cout<<p[i]<<" ";return 0;
}

【NOIP校内模拟】T3 长者(主席树+哈希+二分)相关推荐

  1. 2018.10.16【校内模拟】长者(主席树)(字符串哈希)

    解析: 其实题目已经提示了我们需要用什么数据结构 没睡醒的zxyoizxyoizxyoi考场上打了30pts30pts30pts暴力就直接滚粗了... 一听是正解主席树瞬间明白怎么做... 由于每次修 ...

  2. BZOJ2653 middle 【主席树】【二分】*

    BZOJ2653 middle Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个长度为n的序列s.回答Q个这样 ...

  3. CodeForces - 484E Sign on Fence(主席树区间合并+二分)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的数列,需要回答 mmm 次询问,每次询问的格式如下: lrkl\ r\ kl r k,需要回答区间 [l,r][l,r][l,r] 内,所有长度 ...

  4. CF464E The Classic Problem(主席树+哈希+最短路)

    CF464E The Classic Problem problem solution code problem 题目链接 solution 经典题. 本题很特别的是每条边的边权都是 222 的幂,而 ...

  5. 【UNR #6 C】稳健型选手(分治)(主席树)(二分)

    稳健型选手 题目链接:UNR #6 C 题目大意 有一排卡牌,然后每次询问一个区间,问先手最多的分数. 玩法是先手后手轮流选一张牌拿走,先手任选,后手一定会选最左边的. 然后分数是拿的牌的分数和. 思 ...

  6. 【NOIP校内模拟】T2 华莱士(环套树)

    其实就是要求最小的环套树森林 我们现在只考虑如何合并 设当前边的两个端点是x,y 若x,y在一个联通块里 那这个联通块要么是树 要么是环套树 假如是个环套树 加一条边后必定变成两个环 不符合要求 假如 ...

  7. 20200731 SCOI模拟T3(线段树分治)

    T3 越野赛车问题 思路: 将 l,rl,rl,r 用线段树分治维护 用并查集维护连通性 维护最长链可以对每个连通块记录最长链两端点 合并时设两端点分别是 s,ts,ts,t 和 x,yx,yx,y ...

  8. 【NOIP校内模拟】图论题

    设dis[i]表示根节点到i的距离(只经过树边),再设w[i]表示i到1这条边的距离 对于u和v我们考虑两种情况 ①.当u是v的祖先 则答案为dis[v]-dis[u] ②.当u不是v的祖先,明确从1 ...

  9. 【NOIP校内模拟】塔

    我们可以这样考虑 X 必定是由若干个立方数拼起来的 因此我们可以逆着求 只需关心每次取哪个立方数即可 设a是最大的 a 使得 a^3 不超过 m 分析样例 我们发现在第一次的时候 就可以取a或者a-1 ...

最新文章

  1. FTP服务器之vsftp
  2. oracle与raw device
  3. 在visualc++可以运行的程序在linux下怎么不能,Linux环境下C++只允许单个程序运行...
  4. Mysql执行计划的extra列及filesort祥析
  5. Dom4j SAXReader Constructors
  6. 软件测试简历项目经验介绍,软件测试工程师项目经验简历范文
  7. java hotmail日历,我用java写的日历
  8. 视频教程-玩转Python-Python3基础入门-Python
  9. mysql 小数点多余0_mysql中如何去除小数点后面多余的0
  10. php的amqp扩展 安装(windows) rabbitmq学习篇
  11. linux权限管理详解
  12. Csharp基础整理
  13. 通过ip查看主机名 通过主机名查看ip
  14. 【C语言】sizeof操作符详解
  15. foc学习笔记3——电流环
  16. android 手机屏幕密度等级和屏幕逻辑尺寸
  17. C++中cout的含义????
  18. 基于WebGL架构的3D可视化平台—粮仓3D场景
  19. git@gitlab invalid privatekey
  20. 成功解决老电脑SSD蓝屏问题

热门文章

  1. android 模拟器 docker,如何使用dockerfile在模拟器上构建和运行android apk
  2. pandas中的数据对象Series
  3. android 渐变蒙版_Android实现遮罩层(蒙板)效果
  4. (转载)深度剖析 | 可微分学习的自适配归一化 (Switchable Normalization)
  5. 复试C程序设计(谭浩强版)
  6. B树与B+树的区别!!
  7. 无源型信号隔离器现场应用|信号隔离器-无源信号隔离器-二线制信号隔离器
  8. Matlab由三维散点绘制三维曲面(含等高线,剖面图)
  9. MySQL子查询的空值问题
  10. linux rpm下载网站,推荐几个rpm下载站点