【NOIP2015D2】 解题报告
来源:互联网 发布:香港专业教育学院 知乎 编辑:程序博客网 时间:2024/05/16 17:57
这次模拟考试订正历程很悲催……
Solution
T1:很经典的二分答案,直接切掉
T2:听说过是DP,考试时先写了一个dfs,发现要记录前一个有没有选来看后面的是否连在一起,f[i][j][k][sta]表示A数组前i个,B数组前j个,分成k段,最后两个是否匹配的方案数,一开始忘记选了也可以分为2段,总的方程就是比较a[i+1]和b[j+1],若不同,只能推到f[i+1][j][k][0],若相同,a[i+1]可以不选,就是f[i+1][j][k][0],选,但是自成一段,a[i+1][j+1][k+1][1],或者与前面的合并,但是a[i]得选,f[i+1][j+1][k][1]。
T3:其实一开始不会,一直想不出去掉一条边后怎么计算所有的路径并统计,只会暴力的50分,后来看了题解……发现一开始思路错了,应该想二分,去判断比较简单,就把所有的不符合的路径拿出来,然后记录,然后取所有路径的交集中最长的一条边,看不符合条件的最长的一条路径是否符合即可,思路还算简单。实现上要用树上差分,就是对于路径(u,v),tmp[u]++,tmp[v]++,tmp[lca(u,v)]-=2,tmp[i]表示从i开始向上到根的路径有多少,统计的时候自底向上计算,实现是DFS,先算儿子,父亲tmp+=儿子tmp,记录tmp=cnt的节点,最后判断即可。
订正时遇到的问题:一直WA,吐血的那种,最后发现有些代码没有dfs(v,u),有些代码lca的k只到2(调试时改的),我去。
CODE
T1:
#include<bits/stdc++.h>using namespace std;const int MAXN=50010;int a[MAXN],L,n,m;bool check(int k){ int last=0,cnt=0; for (int i=1;i<=n;i++) if (a[i]-last<k) cnt++; else last=a[i]; if (L-last<k) cnt++; return cnt<=m; }int main(){ scanf("%d%d%d",&L,&n,&m); for (int i=1;i<=n;i++) scanf("%d",&a[i]); int l=0,r=L; while (l<r) { int mid=(l+r+1)>>1; if (check(mid)) l=mid; else r=mid-1; } printf("%d\n",l); }
T2:
#include<bits/stdc++.h>using namespace std;#define MOD 1000000007char a[1010],b[210];int f[2][205][2][205],n,m,K,ans,now;int main(){ scanf("%d%d%d",&n,&m,&K); scanf("%s",a+1); scanf("%s",b+1); n=strlen(a+1); m=strlen(b+1); f[0][0][0][0]=1; now=0; for (int i=0;i<n;i++) { for (int j=0;j<=m;j++) for (int k=0;k<=K;k++) for (int sta=0;sta<=1;sta++) { int p=f[now][j][sta][k]; if (!p) continue; f[1-now][j][0][k]=(f[1-now][j][0][k]+p)%MOD; if (j<m && a[i+1]==b[j+1]) { if (sta) f[1-now][j+1][1][k]=(f[1-now][j+1][1][k]+p)%MOD; f[1-now][j+1][1][k+1]=(f[1-now][j+1][1][k+1]+p)%MOD; } f[now][j][sta][k]=0; } now=1-now; } ans=(f[now][m][0][K]+f[now][m][1][K])%MOD; printf("%d\n",ans); return 0;}
T3:
#include<bits/stdc++.h>using namespace std;const int MAXN=300010,MAXM=300010;int Head[MAXN],tot,n,m,maxdeep,cnt,limit,ans;int fa[MAXN],f[21][MAXN],deep[MAXN],dis[MAXN],tmp[MAXN];struct Edge{ int v,d,next;}edge[MAXN*2];struct node{ int u,v,d,lca;}e[MAXM];void addedge(int x,int y,int z){ edge[++tot]=(Edge){y,z,Head[x]}; Head[x]=tot;}void dfs_pre(int u,int pre){ maxdeep=max(maxdeep,deep[u]); for (int i=Head[u];i;i=edge[i].next) { int v=edge[i].v,d=edge[i].d; if (v==pre) continue; fa[v]=u; deep[v]=deep[u]+1; dis[v]=dis[u]+d; dfs_pre(v,u); } }int query_lca(int u,int v){ if (deep[u]<deep[v]) swap(u,v); int step=deep[u]-deep[v]; for (int k=0;k<=20;k++) if (step & (1<<k)) u=f[k][u]; for (int k=20;k>=0;k--) if (f[k][u]!=f[k][v]) u=f[k][u],v=f[k][v]; return u==v?u:fa[u]; }void calc_lca(){ memset(f,-1,sizeof(f)); int k=log(n)/log(2); for (int i=1;i<=n;i++) f[0][i]=fa[i]; for (int j=1;j<=k;j++) for (int i=1;i<=n;i++) if (f[j-1][i]!=-1) f[j][i]=f[j-1][f[j-1][i]]; for (int i=1;i<=m;i++) { int u=e[i].u,v=e[i].v; e[i].lca=query_lca(u,v); e[i].d=dis[u]+dis[v]-2*dis[e[i].lca]; }}void init(){ scanf("%d%d",&n,&m); for (int i=1;i<n;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); addedge(x,y,z); addedge(y,x,z); } for (int i=1;i<=m;i++) scanf("%d%d",&e[i].u,&e[i].v),e[i].d=0; fa[1]=-1; deep[1]=1; dis[1]=0; dfs_pre(1,1); calc_lca();}int dfs(int u,int pre){ for (int i=Head[u];i;i=edge[i].next) { int v=edge[i].v,d=edge[i].d; if (v==pre) continue; dfs(v,u); if (tmp[v]==cnt) ans=max(ans,d); tmp[u]+=tmp[v]; } return ans;}bool check(int mid){ memset(tmp,0,sizeof(tmp)); cnt=0,limit=0; for (int i=1;i<=m;i++) if (e[i].d>mid) { cnt++; tmp[e[i].u]++; tmp[e[i].v]++; tmp[e[i].lca]-=2; limit=max(limit,e[i].d-mid); } if (!cnt) return true; ans=-1; dfs(1,0); return ans>=limit; }void solve(){ int l=0,r=300000000; while (l<r) { int mid=(l+r)>>1; if (check(mid)) r=mid; else l=mid+1; } printf("%d\n",r); }int main(){ //freopen("transport.in","r",stdin); //freopen("transprot.out","w",stdout); init(); solve(); return 0;}
阅读全文
0 0
- 【NOIP2015D2】 解题报告
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- Antiprime解题报告
- expr解题报告
- 华容道解题报告
- tju解题报告
- zju1062/pku1095解题报告
- UsacoGate解题报告 --- 序曲
- ZJU 2060 解题报告
- ZJU 1331 解题报告
- ZJU 1115 解题报告
- ZJU1057解题报告
- bzoj 2346: [Baltic 2011]Lamp spfa
- sqlyog注册码
- 大数据预科班3
- Atcoder Together
- 数据类型 数据类型转换 运算符
- 【NOIP2015D2】 解题报告
- 用GridView展示已经安装的应用
- jdbc存储过程
- Java基础部分总结3
- setup.py文件
- jdbc的工具类
- SBAS
- #include不同文件夹下的头文件
- 星球联盟