博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NOIP2015D2总结
阅读量:4312 次
发布时间:2019-06-06

本文共 9910 字,大约阅读时间需要 33 分钟。

  今天居然考了一套题。NOIP2015D2。

  这是当年的战绩:

  

  360的一等奖线。好强啊!

  之前做过2015的D1,但我确实不会做landlord……今天曾祥瑞学长和林可学姐都来了,他们说,朱昶宇AK,看见landlord时蒙了便按照自己平时的套路来打程序,看见transport时蒙了便暴力乱搞……

  我不想说,经过了不懈的努力,我才让transport成了95,而他轻轻松松暴力乱搞过了最后那个防AK点。我不想说,当时全省只有他一个人A了这道题。

  太强了!

  好的,现在我们该静一静了。

  第一题,stone,典型的二分答案例题(套贪心),但是二分策略确实很伤人头脑。

 

1 #define PN "stone" 2 #include 
3 int l, n, m, d[50010]; 4 int main() { 5 freopen(PN".in","r",stdin); 6 freopen(PN".out","w",stdout); 7 scanf("%d%d%d",&l,&n,&m); 8 d[0]=0;for( int i = 1; i <= n; i++ ) scanf("%d",&d[i]);d[n+1]=l; 9 int lf=1,rg=l;10 while(lf<=rg) {11 int mid=(lf+rg)>>1, pos=0, num=0;12 for( int i = 1; i <= n+1; i++ ) if(d[i]-d[pos]>=mid) pos=i;else num++;13 if(num<=m) lf=mid+1;14 else rg=mid-1;//?15 }16 printf("%d\n",rg);17 return 0;18 }
stone

 

  第二题,那啥,很明显是可以套路化的,不知道难在哪里。

 

1 #define PN "substring" 2 #include 
3 #include
4 #include
5 int n, m, p, f[2][210][210]; 6 char A[1010], B[210]; 7 inline int add(int a,int b) {
static int MOD=1e9+7;if(a-MOD+b>0) return a-MOD+b;return a+b;} 8 int main() { 9 freopen(PN".in","r",stdin);10 freopen(PN".out","w",stdout);11 scanf("%d%d%d%s%s",&n,&m,&p,A,B);12 memset(f,0,sizeof(f));f[0][0][0]=1;13 for( int i = 1; i <= n; i++ ) for( int j = std::min(i,m); j >= 0; j-- ) for( int k = std::min(i,p); k >= 0; k-- ) {14 f[0][j][k]=add(f[1][j][k],f[0][j][k]);15 if(j!=0&&A[i-1]==B[j-1]) f[1][j][k]=add(add(f[1][j-1][k],f[1][j-1][k-1]),f[0][j-1][k-1]);16 else f[1][j][k]=0;17 }18 printf("%d\n",add(f[0][m][p],f[1][m][p]));19 return 0;20 }
substring

 

  第三题,transport,这道题理论上需要先处理处每个方案的LCA,以及这一段的距离。然后,我们就可以愉快的二分答案。找出那些超了限额的方案,看他们所共有的线路。最值减最值,与mid比较一番,就可以愉快的得出结果了。但是n,m<=300000伤不起啊。

  好的,不多说了。最后一题挂个代码吧。

1 #define PN "transport" 2 #include 
3 #include
4 #include
5 using namespace std; 6 template
inline void readin(T &res) { 7 static char ch;while((ch=getchar())<'0'||ch>'9'); 8 res=ch-48;while((ch=getchar())>='0'&&ch<='9')res=(res<<1)+(res<<3)+ch-48; 9 }10 11 const int N = 300000+10;12 const int M = 300000+10;13 struct EDGE {
int v, upre, w;}g[N];14 int head[N], ne=0;15 inline void adde(int u,int v,int w) {g[++ne]=(EDGE){v,head[u],w},head[u]=ne;}16 17 int n, m, u, v, w, s, t;18 19 const int S = 19;20 int dep[N], anc[N][S+1], dis[N], edg[N], A[M], B[M], C[M], LEN[M];21 void DFS(int u,int fa) {22 anc[u][0]=fa;23 for( int j = 1; j <= S; j++ ) anc[u][j]=anc[anc[u][j-1]][j-1];24 for( int i = head[u]; i; i = g[i].upre ) {25 int v=g[i].v;26 if(v==fa) continue;27 edg[v]=g[i].w;dep[v]=dep[u]+1;dis[v]=dis[u]+g[i].w;DFS(v,u);28 }29 }30 31 int lca(int u,int v) {32 if(dep[u]
>=1,p++ ) if(t&1) u=anc[u][p];34 if(u==v) return u;35 for( int p = S; anc[u][0]!=anc[v][0]; p-- ) if(anc[u][p]!=anc[v][p]) u=anc[u][p], v=anc[v][p];36 return anc[u][0];37 }38 39 int counter, maxl=0, flag[N], ans;40 void DFS1(int u,int fa) {41 for( int i = head[u]; i; i = g[i].upre ) {42 int v = g[i].v;43 if(v==fa) continue;44 DFS1(v,u);45 flag[u]+=flag[v];46 }47 if(flag[u]==counter) ans=max(ans,edg[u]);48 }49 bool check(int limit) {50 ans=0;counter=0;memset(flag,0,sizeof(flag));for( int i = 1; i <= m; i++ ) if(LEN[i]>limit) counter++, flag[A[i]]++, flag[B[i]]++, flag[C[i]]-=2;51 DFS1(1,1);return maxl-ans<=limit;52 }53 54 int main() {55 freopen(PN".in","r",stdin);56 freopen(PN".out","w",stdout);57 readin(n);readin(m);for( int i = 1; i < n; i++ ) {readin(u);readin(v);readin(w);adde(u,v,w);adde(v,u,w);}58 DFS(1,1);59 for( int i = 1; i <= m; i++ ) {60 readin(A[i]);readin(B[i]);C[i]=lca(A[i],B[i]);61 LEN[i]=dis[A[i]]+dis[B[i]]-dis[C[i]]*2;maxl=max(maxl,LEN[i]);62 }63 int lf=0, rg=maxl-1;64 while(lf<=rg) {65 int mid=(lf+rg)>>1;66 if(check(mid)) rg=mid-1;67 else lf=mid+1;68 }69 printf("%d\n",rg+1);70 return 0;71 }
transport

   后来:啊啊啊啊啊。我把最开始求LCA的ST表倍增换成了并查集tarjan,在教师老年机上又WA又T(后来经过考究,是因为u==v时tarjan的bug)。但我在BZOJ上交了一下。 

并查集tarjan  Accepted
36200 kb  9528 ms
ST表倍增 Accepted 46452 kb 9700 ms

  是为什么?人品吗?

1 /************************************************************** 2     Problem: 4326 3     User: Doggu 4     Language: C++ 5     Result: Accepted 6     Time:9528 ms 7     Memory:36200 kb 8 ****************************************************************/ 9  10 #define PN "transport"11 #include 
12 #include
13 #include
14 using namespace std;15 template
inline void readin(T &res) {16 static char ch;while((ch=getchar())<'0'||ch>'9');17 res=ch-48;while((ch=getchar())>='0'&&ch<='9')res=(res<<1)+(res<<3)+ch-48;18 }19 20 const int N = 300000+10;21 const int M = 300000+10;22 struct EDGE {
int v, upre, w, lca;}g[N*2], r[M*2];23 int head[N], ne=0, read[N], re=0;24 inline void adde(int u,int v,int w) {g[++ne]=(EDGE){v,head[u],w},head[u]=ne;}25 inline void addr(int u,int v,int w) {r[++re]=(EDGE){v,read[u],w},read[u]=re;}26 27 int n, m, u, v, w, s, t;28 29 int fax[N], dis[N], edg[N], A[M], B[M], C[M], LEN[M];30 bool vis[N];31 int find(int x) {32 if(fax[x]==x) return x;33 return fax[x]=find(fax[x]);34 }35 void DFS(int u,int fa) {36 for( int i = head[u]; i; i = g[i].upre ) {37 int v=g[i].v;38 if(v==fa) continue;39 edg[v]=g[i].w;dis[v]=dis[u]+g[i].w;DFS(v,u);40 fax[v]=find(u);vis[v]=1;41 }42 for( int i = read[u]; i; i = r[i].upre ) if(vis[r[i].v]) r[i].lca=find(r[i].v);43 }44 45 int counter, maxl=0, flag[N], ans;46 void DFS1(int u,int fa) {47 for( int i = head[u]; i; i = g[i].upre ) {48 int v = g[i].v;49 if(v==fa) continue;50 DFS1(v,u);51 flag[u]+=flag[v];52 }53 if(flag[u]==counter) ans=max(ans,edg[u]);54 }55 bool check(int limit) {56 ans=0;counter=0;memset(flag,0,sizeof(flag));for( int i = 1; i <= m; i++ ) if(LEN[i]>limit) counter++, flag[A[i]]++, flag[B[i]]++, flag[C[i]]-=2;57 DFS1(1,1);return maxl-ans<=limit;58 }59 60 int main() {61 //freopen(PN".in","r",stdin);62 //freopen(PN".out","w",stdout);63 readin(n);readin(m);for( int i = 1; i < n; i++ ) {readin(u);readin(v);readin(w);adde(u,v,w);adde(v,u,w);}64 for( int i = 1; i <= m; i++ ) {readin(A[i]);readin(B[i]);addr(A[i],B[i],i);addr(B[i],A[i],i);}65 for( int i = 1; i <= n; i++ ) fax[i]=i;memset(vis,0,sizeof(vis));66 DFS(1,1);for( int i = 1; i <= re; i++ ) if(r[i].lca) C[r[i].w]=r[i].lca;67 for( int i = 1; i <= m; i++ ) LEN[i]=dis[A[i]]+dis[B[i]]-dis[C[i]]*2, maxl=max(maxl,LEN[i]);68 int lf=0, rg=maxl-1;69 while(lf<=rg) {70 int mid=(lf+rg)>>1;71 if(check(mid)) rg=mid-1;72 else lf=mid+1;73 }74 printf("%d\n",rg+1);75 return 0;76 }77
Tarjan并查集
1 /************************************************************** 2     Problem: 4326 3     User: Doggu 4     Language: C++ 5     Result: Accepted 6     Time:9700 ms 7     Memory:46452 kb 8 ****************************************************************/ 9  10 #define PN "transport"11 #include 
12 #include
13 #include
14 using namespace std;15 template
inline void readin(T &res) {16 static char ch;while((ch=getchar())<'0'||ch>'9');17 res=ch-48;while((ch=getchar())>='0'&&ch<='9')res=(res<<1)+(res<<3)+ch-48;18 }19 20 const int N = 300000+10;21 const int M = 300000+10;22 struct EDGE {
int v, upre, w;}g[N*2];23 int head[N], ne=0;24 inline void adde(int u,int v,int w) {g[++ne]=(EDGE){v,head[u],w},head[u]=ne;}25 26 int n, m, u, v, w, s, t;27 28 const int S = 19;29 int dep[N], anc[N][S+1], dis[N], edg[N], A[M], B[M], C[M], LEN[M];30 void DFS(int u,int fa) {31 anc[u][0]=fa;32 for( int j = 1; j <= S; j++ ) anc[u][j]=anc[anc[u][j-1]][j-1];33 for( int i = head[u]; i; i = g[i].upre ) {34 int v=g[i].v;35 if(v==fa) continue;36 edg[v]=g[i].w;dep[v]=dep[u]+1;dis[v]=dis[u]+g[i].w;DFS(v,u);37 }38 }39 40 int lca(int u,int v) {41 if(dep[u]
>=1,p++ ) if(t&1) u=anc[u][p];43 if(u==v) return u;44 for( int p = S; anc[u][0]!=anc[v][0]; p-- ) if(anc[u][p]!=anc[v][p]) u=anc[u][p], v=anc[v][p];45 return anc[u][0];46 }47 48 int counter, maxl=0, flag[N], ans;49 void DFS1(int u,int fa) {50 for( int i = head[u]; i; i = g[i].upre ) {51 int v = g[i].v;52 if(v==fa) continue;53 DFS1(v,u);54 flag[u]+=flag[v];55 }56 if(flag[u]==counter) ans=max(ans,edg[u]);57 }58 bool check(int limit) {59 ans=0;counter=0;memset(flag,0,sizeof(flag));for( int i = 1; i <= m; i++ ) if(LEN[i]>limit) counter++, flag[A[i]]++, flag[B[i]]++, flag[C[i]]-=2;60 DFS1(1,1);return maxl-ans<=limit;61 }62 63 int main() {64 //freopen(PN".in","r",stdin);65 //freopen(PN".out","w",stdout);66 readin(n);readin(m);for( int i = 1; i < n; i++ ) {readin(u);readin(v);readin(w);adde(u,v,w);adde(v,u,w);}67 DFS(1,1);68 for( int i = 1; i <= m; i++ ) {69 readin(A[i]);readin(B[i]);C[i]=lca(A[i],B[i]);70 LEN[i]=dis[A[i]]+dis[B[i]]-dis[C[i]]*2;maxl=max(maxl,LEN[i]);71 }72 int lf=0, rg=maxl-1;73 while(lf<=rg) {74 int mid=(lf+rg)>>1;75 if(check(mid)) rg=mid-1;76 else lf=mid+1;77 }78 printf("%d\n",rg+1);79 return 0;80 }
ST表倍增

   不过,昶宇哥确实快炸了……我犯大不韪地交了一下他的,却发现早有人交过了……

14 1182623 36952 KB 2992 MS C++ 4689 B 2015-12-05 09:31:34
15 2139716(3) 36972 KB 2992 MS 4689 B 2017-07-02 08:57:28

  

转载于:https://www.cnblogs.com/Doggu/p/test20170701.html

你可能感兴趣的文章
VNPY- VnTrader基本使用
查看>>
VNPY - CTA策略模块策略开发
查看>>
VNPY - 事件引擎
查看>>
MongoDB基本语法和操作入门
查看>>
学习笔记_vnpy实战培训day04_作业
查看>>
OCO订单(委托)
查看>>
学习笔记_vnpy实战培训day06
查看>>
回测引擎代码分析流程图
查看>>
Excel 如何制作时间轴
查看>>
matplotlib绘图跳过时间段的处理方案
查看>>
vnpy学习_04回测评价指标的缺陷
查看>>
iOS开发中遇到的问题整理 (一)
查看>>
Linux(SUSE 12)安装jboss4并实现远程访问
查看>>
Neutron在给虚拟机分配网络时,底层是如何实现的?
查看>>
netfilter/iptables全攻略
查看>>
Overlay之VXLAN架构
查看>>
Eclipse : An error occurred while filtering resources(Maven错误提示)
查看>>
在eclipse上用tomcat部署项目404解决方案
查看>>
web.xml 配置中classpath: 与classpath*:的区别
查看>>
suse如何修改ssh端口为2222?
查看>>