闲扯

先看看了B组,T1 ZROI刚好讲过一个性质原根一般很小的,直接枚举;T2一眼二分然后似乎状压 T3没看

然后上来A组题,T1 flow这名字...网络流?!

T1题面非常的社会主义核心价值观,看到有个\(m==n\)的限制就想如果去掉怎么样,发现一棵树的话答案是确定的,然后考虑加上那条多出来的边,发现答案还是不变的?!想了想好像确实是这样,你树边确定了环边根本不用管,判断有无解就是点值加起来是否为0.于是直接DFS扫一遍去掉环边再DFS一遍就好了

T2 题面1984还行 出题人小心啊 扫了一眼觉得好难告辞

T3 第一眼题面 woc!!求求你们给国家省点子弹,我觉得博客中贴出这题题面的也要被查睡标了

第二眼woc?!这不是雅礼集训讲过的原题吗?!还记得点思路就是预处理坐几班车最远可到达的地方,讲题人还提到了长链剖分

于是肛肛肛...结果死活没调出来...然后xxzh巨佬讲了一种更好写的暴力....感觉以后考试看到原题还是得想想有没有其他的思路

结果15+0+0 T1 TM 正负号打反了,又犯SB错误 心态崩了

T1 flow

分析

某div 2 F竟这么水(你还不是挂分了)

见闲扯

代码

  1. /*
  2. code by RyeCatcher
  3. */
  4. inline char gc(){
  5. static char buf[SIZE],*p1=buf,*p2=buf;
  6. return p1==p2&&(p2=(p1=buf)+fread(buf,1,SIZE,stdin),p1==p2)?EOF:*p1++;
  7. }
  8. #define gc getchar
  9. template <class T>inline void read(T &x){
  10. x=0;int ne=0;char c;
  11. while((c=gc())>'9'||c<'0')ne=c=='-';x=c-48;
  12. while((c=gc())>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48;x=ne?-x:x;return ;
  13. }
  14. const int maxn=200005;
  15. const int inf=0x7fffffff;
  16. struct Edge{
  17. int ne,to,id;
  18. bool ok;
  19. }edge[maxn<<2];
  20. int h[maxn],num_edge=1;
  21. inline void add_edge(int f,int to,int id){
  22. edge[++num_edge].ne=h[f];
  23. edge[num_edge].to=to;
  24. edge[num_edge].id=id;
  25. edge[num_edge].ok=0;
  26. h[f]=num_edge;
  27. }
  28. int w[maxn];
  29. struct Nico{
  30. int x,y,id,dis;
  31. }nico[maxn<<2];
  32. struct QAQ{
  33. int x,y,fff;
  34. int xd,yd;
  35. }yyy[maxn<<2];
  36. int tot=0;
  37. int n,m;
  38. namespace fake{
  39. ll ans=0;
  40. bool vis[maxn];
  41. int fa[maxn];
  42. void gao_cyc(int now){//去非树边
  43. int v;
  44. vis[now]=1;
  45. for(ri i=h[now];i;i=edge[i].ne){
  46. v=edge[i].to;
  47. if(v==fa[now])continue;
  48. if(vis[v]){
  49. edge[i].ok=edge[i^1].ok=1;
  50. }
  51. if(edge[i].ok)continue;
  52. fa[v]=now;
  53. gao_cyc(v);
  54. }
  55. return ;
  56. }
  57. void get_ans(int now){
  58. int v,id=0;
  59. for(ri i=h[now];i;i=edge[i].ne){
  60. v=edge[i].to;
  61. if(edge[i].ok)continue;
  62. if(v==fa[now]){
  63. id=edge[i].id;continue;
  64. }
  65. get_ans(v);
  66. }
  67. yyy[++tot].x=now,yyy[tot].y=fa[now];
  68. yyy[tot].xd=-w[now],yyy[tot].yd=w[now];
  69. yyy[tot].fff=id;
  70. w[fa[now]]+=w[now];
  71. return ;
  72. }
  73. void main(){
  74. int x,y,a,b;
  75. for(ri i=1;i<=n;i++){
  76. ans+=w[i];
  77. }
  78. memset(vis,0,sizeof(vis));
  79. if(ans==0)puts("Possible");
  80. else{
  81. puts("Impossible");
  82. return ;
  83. }
  84. fa[1]=0;
  85. gao_cyc(1);
  86. get_ans(1);
  87. for(ri i=1;i<=tot;i++){
  88. x=yyy[i].x,y=yyy[i].y;
  89. a=nico[yyy[i].fff].x,b=nico[yyy[i].fff].y;
  90. //printf("%d %d %d %d\n",x,y,a,b);
  91. if(x==a&&y==b){
  92. nico[yyy[i].fff].dis=-yyy[i].xd;
  93. }
  94. else if(x==b&&y==a){
  95. nico[yyy[i].fff].dis=-yyy[i].yd;
  96. }
  97. }
  98. for(ri i=1;i<=m;i++){
  99. printf("%d\n",-nico[i].dis);
  100. }
  101. return ;
  102. }
  103. }
  104. int main(){
  105. int x,y;
  106. FO(flow);
  107. read(n);
  108. for(ri i=1;i<=n;i++)read(w[i]);
  109. read(m);
  110. for(ri i=1;i<=m;i++){
  111. read(x),read(y);
  112. add_edge(x,y,i);
  113. add_edge(y,x,i);
  114. nico[i].x=x,nico[i].y=y,nico[i].dis=0;
  115. }
  116. //if(m<=20&&n<=20)bf::main();
  117. fake::main();
  118. return 0;
  119. }

T2 moon

T3 car

  • 前置技能点

    • 倍增
    • 扫描线
    • dfs序

预处理每个点在一条链上坐\(2^j\)次车最远到哪里,这显然可以倍增搞

然后考虑答案怎么算

对于询问\((x,y)\),求出\(z=lca(x,y)\),\(x,y\)先分别跳到距\(z\)最近的点(也就是下次就到\(z\)或更远),这时候先统计个答案步数\(ans\)

然后发现答案只有两种情况

Case#1

两点分别跳一次到\(z\),最终\(ans=ans+2\)

Case#2

设这时候\(x,y\)分别跳到了\(x',y'\)

有一班车覆盖了路径\((x',y')\),那么答案就是\(ans=ans+1\),因为你只要坐这班车就可以越过LCA到另一个点

考虑怎么判断有没有一班车覆盖这条路径,转化一下变成是否有一班车\((st,ed)\),\(st\)在\(x'\)子树中,\(ed\)在\(y'\)子树中(包括\(x'.y'\))

如果你看过https://rye-catcher.github.io/2018/10/17/JZOI100019-A-dfs%E5%BA%8F-%E6%89%AB%E6%8F%8F%E7%BA%BF/

就会发现这还可以继续转化成\(dfn[x']<=dfn[st]<=ed[x'],dfn[y']<=dfn[ed]<=ed[y']\)

将\((dfn[st],dfn[ed])\)看成一个坐标,发现就是判断一个矩形中有没有点

似乎可以在线主席树做,也好像可以二分套二分,这里学到了一个新操作树状数组+扫描线+二维前缀和

我们转化后询问\((x',y')\)矩形的四个坐标为\((dfn[x'],dfn[y']),(dfn[x'],ed[y']),(ed[x'],dfn[y']),(ed[x'],ed[y'])\)

一条班车路径转化成一个点\((dfn[st],dfn[ed])\)

我们把这些点放在一起按照扫描线思路,将点按横坐标进行排序,然后遍历所有点(优先遍历班车路径转化后的点)

如果是班车路径的点,加入树状数组\([1,dfn[ed]]\)(\(dfn[ed]\)其实就是坐标(x,y)中的\(y\))前缀和

如果是个矩形想要查询里面点数咋办?二维前缀和.

我们是将所有点按横坐标排序的,所以我们可以先加上\(B\)的点数,减去\(A+B\)的点数,然后等到\(ed[x']\)坐标时减去\(B+C\) 点数,最后加上整个大面积就是矩形内点数

显然这些部分直接查询树状数组前缀和就好了

然后有非常多的细节,见代码注释吧...

对于树上路径,我们都默认dfs序小的为起点方便处理,也算是个技巧

  1. /*
  2. code by RyeCatcher
  3. */
  4. inline char gc(){
  5. static char buf[SIZE],*p1=buf,*p2=buf;
  6. return p1==p2&&(p2=(p1=buf)+fread(buf,1,SIZE,stdin),p1==p2)?EOF:*p1++;
  7. }
  8. template <class T>inline void read(T &x){
  9. x=0;int ne=0;char c;
  10. while((c=gc())>'9'||c<'0')ne=c=='-';x=c-48;
  11. while((c=gc())>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48;x=ne?-x:x;return ;
  12. }
  13. const int maxn=500005;
  14. const int inf=0x7fffffff;
  15. int n,m,q;
  16. struct Edge{
  17. int ne,to;
  18. }edge[maxn<<1];
  19. int h[maxn],num_edge=1;
  20. inline void add_edge(int f,int to){
  21. edge[++num_edge].ne=h[f];
  22. edge[num_edge].to=to;
  23. h[f]=num_edge;
  24. }
  25. int f[maxn][23];
  26. int dep[maxn],fa[maxn],son[maxn],size[maxn],top[maxn],dfn[maxn],ed[maxn],tot=0;
  27. void dfs_1(int now){
  28. int v;size[now]=1;
  29. //if(now==150000)printf("wtf %d\n",now,fa[now]);
  30. for(ri i=h[now];i;i=edge[i].ne){
  31. v=edge[i].to;
  32. if(v==fa[now])continue;
  33. dep[v]=dep[now]+1,fa[v]=now;
  34. dfs_1(v);
  35. size[now]+=size[v];
  36. if(!son[now]||size[v]>size[son[now]])son[now]=v;
  37. }
  38. return ;
  39. }
  40. void dfs_2(int now,int t){
  41. int v;
  42. dfn[now]=++tot,top[now]=t;
  43. if(!son[now]){
  44. ed[now]=tot;
  45. return ;
  46. }
  47. dfs_2(son[now],t);
  48. for(ri i=h[now];i;i=edge[i].ne){
  49. v=edge[i].to;
  50. if(v==fa[now]||v==son[now])continue;
  51. dfs_2(v,v);
  52. }
  53. ed[now]=tot;
  54. return ;
  55. }
  56. inline int get_lca(int x,int y){
  57. int xx=x,yy=y;
  58. while(top[x]!=top[y]){
  59. if(dep[top[x]]<dep[top[y]])std::swap(x,y);
  60. x=fa[top[x]];
  61. }
  62. //if(!x)printf("--%d %d %d--\n",xx,yy,x);
  63. if(dep[x]>dep[y])return y;
  64. return x;
  65. }
  66. void pre_dfs(int now){
  67. int v;
  68. for(ri i=h[now];i;i=edge[i].ne){
  69. v=edge[i].to;
  70. if(v==fa[now])continue;
  71. pre_dfs(v);
  72. if(!f[now][0]||(f[v][0]&&dep[f[now][0]]>dep[f[v][0]]))f[now][0]=f[v][0];//特判
  73. }
  74. return ;
  75. }
  76. struct Seg{
  77. int x,y,id,d;
  78. bool operator <(const Seg &rhs)const{
  79. return (x==rhs.x)?id<rhs.id:x<rhs.x;
  80. }
  81. }seg[maxn<<2];
  82. int sum[maxn<<2];
  83. inline void update(int x,int k){for(;x<=n;x+=x&(-x))sum[x]+=k;}
  84. inline int query(int x){
  85. int tmp=0;
  86. for(;x>=1;x-=x&(-x))tmp+=sum[x];
  87. return tmp;
  88. }
  89. int fac[maxn],ans[maxn];
  90. int qwq=0,pt[maxn];
  91. int main(){
  92. int x,y,lca;
  93. //DEBUG
  94. read(n);
  95. fa[1]=0;
  96. f[1][0]=1;
  97. for(ri i=2;i<=n;i++){
  98. f[i][0]=i;
  99. read(fa[i]);
  100. add_edge(i,fa[i]),add_edge(fa[i],i);
  101. }
  102. dep[1]=0;
  103. dfs_1(1);
  104. dfs_2(1,1);
  105. read(m);
  106. for(ri i=1;i<=m;i++){
  107. read(x),read(y);
  108. if(dfn[x]>dfn[y])std::swap(x,y);
  109. lca=get_lca(x,y);
  110. if(!f[x][0]||dep[f[x][0]]>dep[lca])f[x][0]=lca;
  111. if(!f[y][0]||dep[f[y][0]]>dep[lca])f[y][0]=lca;
  112. seg[++qwq]=(Seg){dfn[x],dfn[y],0,1};
  113. }
  114. pre_dfs(1);
  115. fac[0]=1;
  116. for(ri i=1;i<=n;i++)if(f[i][0]==i){
  117. f[i][0]=0;//注意这里要置为不可行
  118. }
  119. for(ri k=1;k<=21;k++){
  120. fac[k]=(fac[k-1]<<1);
  121. for(ri i=1;i<=n;i++)f[i][k]=f[f[i][k-1]][k-1];
  122. }
  123. //for(ri k=0;k<=2;k++)for(ri i=1;i<=n;i++)printf("%d %d %d\n",i,k,f[i][k]);
  124. int po,qo;
  125. read(q);
  126. for(ri o=1;o<=q;o++){
  127. read(x),read(y);
  128. if(dfn[x]>dfn[y])std::swap(x,y);
  129. lca=get_lca(x,y);
  130. po=x,qo=y;
  131. for(ri i=21;i>=0;i--)
  132. if(dep[f[po][i]]>dep[lca]){
  133. po=f[po][i];
  134. ans[o]+=fac[i];
  135. }
  136. for(ri i=21;i>=0;i--)
  137. if(dep[f[qo][i]]>dep[lca]){
  138. qo=f[qo][i];
  139. ans[o]+=fac[i];
  140. }
  141. if((!f[po][0]&&po!=lca)||(!f[qo][0]&&qo!=lca)){//注意!!
  142. ans[o]=-1;
  143. }
  144. else {
  145. if(po==lca||qo==lca){
  146. ans[o]++;
  147. //printf("--%d %d--\n",o,ans[o]);
  148. }
  149. else {
  150. ans[o]+=2;
  151. //printf("--%d %d--\n",o,ans[o]);
  152. seg[++qwq]=(Seg){dfn[po]-1,dfn[qo]-1,o,1};//二维前缀和
  153. seg[++qwq]=(Seg){ed[po],ed[qo],o,1};
  154. seg[++qwq]=(Seg){dfn[po]-1,ed[qo],o,-1};
  155. seg[++qwq]=(Seg){ed[po],dfn[qo]-1,o,-1};
  156. }
  157. }
  158. }
  159. std::sort(seg+1,seg+1+qwq);
  160. for(ri i=1;i<=qwq;i++){
  161. if(!seg[i].id){
  162. update(seg[i].y,seg[i].d);
  163. }
  164. else{
  165. pt[seg[i].id]+=seg[i].d*query(seg[i].y);
  166. }
  167. }
  168. for(ri i=1;i<=q;i++){
  169. if(pt[i])printf("%d\n",ans[i]-1);
  170. else printf("%d\n",ans[i]);
  171. }
  172. return 0;
  173. }

[NOIP2018模拟赛10.20A]挂分报告的更多相关文章

  1. [NOIP2018模拟赛10.16]手残报告

    [NOIP2018模拟赛10.16]手残报告 闲扯 炉石乱斗模式美滋滋啊,又颓到好晚... 上来T2先敲了树剖,看T1发现是个思博DP,然后没过大样例,写个暴力发现还是没过大样例!?才发现理解错题意了 ...

  2. [NOIP2018模拟赛10.25]瞎搞报告

    闲扯 最近有点颓,都修到好晚,早上起来和吔shi一样难受 忍着困意把题面看完,发现啥也不会,又是一场写暴力的模拟赛 T1发现似乎可以DP,顺手码了个 T2像个最小瓶颈路板子,但是只做过N^2算法的.. ...

  3. [NOIP2018模拟赛10.18]自闭报告

    闲扯 这一天,菜鸡RyeCatcher又想起来了被毒瘤题支配的恐惧 今天比较好玩,还是ljy提醒才发现文件夹里有题面...不知道外面的人什么时候才发现 看完了题面,又回到了雅礼啥题也不会写的感觉 T1 ...

  4. [NOIP2018模拟赛10.22]咕咕报告

    闲扯 这是篇咕咕了的博客 考场上码完暴力后不知道干什么,然后忽然发现这个T1好像有点像一道雅礼集训时讲过的CF题目 Rest In Shades ,当时那道题还想了挺久不过思路比较妙,于是我就也\(y ...

  5. [NOIP2018模拟赛10.23]发呆报告

    闲扯 考场看了眼题目感觉很难,一个小时敲完了所有暴力...嗯然后就在那里发呆什么事也没做 T3考场上把数据结构想了个遍都不会完成1操作,现在看这种思路其实之前也接触过... 比较玄学的一件事情就是T1 ...

  6. [NOIP2018模拟赛10.19]只会暴力报告

    闲扯 今天又是暴力满满(并不)的一天呢 昨天老师说了分数要正态分布,今天看起来...不过暴力分很多,虽然我人太傻逼又没打满 T1 woc?不是说送分的吗,看起来又是个树形DP神题,暴力告辞,链上的搞一 ...

  7. NOIP2017提高组模拟赛 10 (总结)

    NOIP2017提高组模拟赛 10 (总结) 第一题 机密信息 FJ有个很奇怪的习惯,他把他所有的机密信息都存放在一个叫机密盘的磁盘分区里,然而这个机密盘中却没有一个文件,那他是怎么存放信息呢?聪明的 ...

  8. EZ 2018 06 10 NOIP2018 模拟赛(十八)

    好久没写blog&&比赛题解了,最近补一下 这次还是很狗的,T3想了很久最后竟然连并查集都忘写了,然后T2map莫名爆炸. Rating爆减......链接不解释 好了我们开始看题. ...

  9. EZ 2018 06 17 NOIP2018 模拟赛(十九)

    这次的题目难得的水,但是由于许多哲学的原因,第二题题意表述很迷. 然后是真的猜题意了搞了. 不过这样都可以涨Rating我也是服了. Upt:链接莫名又消失了 A. 「NOIP2017模拟赛11.03 ...

随机推荐

  1. vue 引入公共css文件

    1.在入口js文件main.js中引入,一些公共的样式文件,可以在这里引入. import Vue from 'vue'import App from './App' // 引入App这个组件impo ...

  2. git notes的使用

    1. 获取notes git fetch origin refs/notes/*:refs/notes/* 2. 设置notes 2.1 git config --add core.notesRef ...

  3. LeetCode_66. Plus One

    66. Plus One Easy Given a non-empty array of digits representing a non-negative integer, plus one to ...

  4. Centos7彻底删除PHP

    查看php版本命令: #php -v 下面的命令是删除不干净的 #yum remove php 因为使用这个命令以后再用 #php -v 还是会看到有版本信息的..... 必须强制删除,使用下面命令查 ...

  5. MySQL 5.7 源码中的目录结构

    MySQl Server的源码可以直接去Github浏览. 这里我们选择5.7版本的:https://github.com/mysql/mysql-server/tree/5.7 也可以通过: git ...

  6. Windows VS2017 编译 libssh2 1.7.0(执行命令、文件上传、下载)

    下载安装 OpenSSL 要编译 libssh2,必须先编译好 OpenSSL 的静态库,直接从 http://slproweb.com/products/Win32OpenSSL.html 下载已经 ...

  7. EM算法之不同的推导方法和自己的理解

    EM算法之不同的推导方法和自己的理解 一.前言 EM算法主要针对概率生成模型解决具有隐变量的混合模型的参数估计问题. 对于简单的模型,根据极大似然估计的方法可以直接得到解析解:可以在具有隐变量的复杂模 ...

  8. 最新 中至数据java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.中至数据等10家互联网公司的校招Offer,因为某些自身原因最终选择了中至数据.6.7月主要是做系统复习.项目复盘.Leet ...

  9. 国产龙芯服务器源码安装PostgreSQL数据库的方法

    1. 公司最近有一些国产化项目的需求, 要求在国产CPU的服务器上面安装pg数据库等. 2.. 但是差查了下中标麒麟的官网,在龙芯MIPS的操作系统包源里面仅有 postgreSQL 9.2 版本的r ...

  10. Java面试题代码篇

    1.统计字符串中的各种字符的个数并对其排序 package JavaMianSiTest; public class TongJIZiFu { public static void main(Stri ...