A: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=83690#problem/A
题意:N*M的格子,从左上走到右下,要求在每个点的权值必须大于0,问起始的时候必须有多少能量
思路:二分答案

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> using namespace std; typedef long long LL; const int maxn=510; const int maxm=1010; const int MOD=1e9+7; const int INF=0x3f3f3f3f; int N,M; int a[maxn][maxn]; int dp[maxn][maxn]; bool can(int x){ for(int i=0;i<=N;i++){ for(int j=0;j<=M;j++){ dp[i][j]=-INF; } } dp[1][1]=x; if(dp[1][1]<=0)return false; for(int i=1;i<=N;i++){ for(int j=1;j<=M;j++){ if(i==1&&j==1)continue; dp[i][j]=max(dp[i-1][j],dp[i][j-1])+a[i][j]; if(dp[i][j]<=0)dp[i][j]=-INF; } } return dp[N][M]>=0; } int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d%d",&N,&M); for(int i=1;i<=N;i++){ for(int j=1;j<=M;j++){ scanf("%d",&a[i][j]); } } int l=0,r=INF; while(l<r){ int mid=(l+r)>>1; if(can(mid))r=mid; else l=mid+1; } printf("%d\n",r); } return 0; }

D: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=83690#problem/D

题意:N个人,两两之间比赛,然后告诉你每个人赢了多少场,但里面存在错误,问最小修改多少分,能符合常理
思路:每次枚举分数最高的,然后把他输得分配下去,更新答案

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> using namespace std; typedef long long LL; const int maxn=100010; const int maxm=1010; const int MOD=1e9+7; const int INF=0x3f3f3f3f; int N; int a[maxn]; int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d",&N); int sum=0; for(int i=1;i<=N;i++){ scanf("%d",&a[i]); } int ans=0; for(int i=N;i>=1;i--){ sort(a+1,a+1+i); if(a[i]>=i){ ans+=a[i]-i+1; a[i]=i-1; } int cha=i-a[i]-1; for(int j=i-1;j>=i-cha;j--){ a[j]--; if(a[j]<0){ ans++; a[j]=0; } } } printf("%d\n",ans); } return 0; }

前1个人,至少0场胜利,他可能全部败给后面的人,也可能赢了后面某几个人。
前2个人,至少要有1场胜利,他们之间必须有一人获胜,如果不够,就需要补足。如果大于1,表示他们之中有人赢了后面某几人。
前3个人,至少要有3场胜利 ………………
前4个人,至少要有6场胜利 ………………
等等…………
前n个人(即所有的人)时,至少要有n(n-1)/2场胜利,不够则补足。但如果大于n(n-1)/2,就表示胜利场数超了,此时需要将胜利场数更改回n(n-1)/2 。

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std; int main(){ int s[51],p[51]; int t,i,n,res; for(cin>>t;t--;){ cin>>n; for(i=0,res=0;i<n;i++){ cin>>s[i]; p[i]=i?p[i-1]+i:0; } sort(s,s+n); for(i=0;i<n;i++){ s[i]=i?s[i-1]+s[i]:s[i]; if(p[i]>=s[i]) res+=p[i]-s[i],s[i]=p[i]; } cout<<res+s[n-1]-p[n-1]<<endl; } return 0; } 

H: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=83690#problem/H
题意:找有多少个字串包含最大值和最小值,找有多少个子序列包含最大值最小值
思路:对于第一个,可以预处理出里每个位置最近的最大值和最小值,然后枚举开头。对于第二问设最大值的个数为cnt1,最小值的个数为cnt2,那么答案就是2N−2N−cnt1−2N−cnt2+2N−cnt1−cnt2

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> using namespace std; typedef long long LL; const int maxn=100010; const int maxm=1010; const int MOD=1e9+7; const int INF=0x3f3f3f3f; int N; int a[maxn]; LL f[maxn]; int pos[maxn][2]; void solve(){ int minv=INF,maxv=-INF; int cnt1=0,cnt2=0; for(int i=1;i<=N;i++){ if(a[i]<minv){ minv=a[i]; cnt1=1; } else if(a[i]==minv){ cnt1++; } if(a[i]>maxv){ maxv=a[i]; cnt2=1; } else if(a[i]==maxv){ cnt2++; } } LL ans1=0,ans2=0; if(maxv==minv){ ans1=(1LL*(N+1)*N/2)%MOD; ans2=f[N]-1; printf("%lld %lld\n",ans1,ans2); return; } ans2=(f[N]-f[N-cnt1]-f[N-cnt2]+f[N-cnt1-cnt2])%MOD; int pos1=-1,pos2=-1; ans1=0; for(int i=N;i>=1;i--){ if(a[i]==minv)pos1=i; if(a[i]==maxv)pos2=i; pos[i][0]=pos1,pos[i][1]=pos2; } for(int i=1;i<=N;i++){ if(pos[i][0]!=-1&&pos[i][1]!=-1){ int x=max(pos[i][0],pos[i][1]); ans1+=N-(x-1); if(ans1>=MOD)ans1-=MOD; } } printf("%lld %lld\n",ans1,(ans2+MOD)%MOD); } int main(){ f[0]=1; for(int i=1;i<maxn;i++){ f[i]=f[i-1]*2%MOD; } int T; scanf("%d",&T); while(T--){ scanf("%d",&N); for(int i=1;i<=N;i++){ scanf("%d",&a[i]); } solve(); } return 0; }

I: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=83690#problem/I
题意:每条龙都有一个生存周期,也会有一个父亲,问每条龙存在的时候,最多跟他的子孙隔多少代
思路:因为要查询他的子孙,所以首先对每个节点求出dfs序,隔多少代其实就是树中深度差多少,然后按照d(死亡时间)排序,离线处理,对于出生时间h小于d的都加进去,然后查询,具体看代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> using namespace std; typedef long long LL; const int maxn=100010; const int maxm=1010; const int MOD=1e9+7; const int INF=0x3f3f3f3f; struct node{ int h,d,p,id; node(){} node(int _p,int _h,int _d,int _id):p(_p),h(_h),d(_d),id(_id){} }a[maxn],b[maxn]; int dfn[maxn],dep[maxn],num[maxn]; int dfs_clock; int N; vector<int> G[maxn]; struct IntervalTree{ int maxv[maxn<<2]; void build(int o,int l,int r){ maxv[o]=0; if(l==r){ return ; } int mid=(l+r)>>1; build(o<<1,l,mid); build(o<<1|1,mid+1,r); } void update(int o,int l,int r,int x,int val){ if(l==r){ maxv[o]=val; return ; } int mid=(l+r)>>1; if(x<=mid)update(o<<1,l,mid,x,val); else update(o<<1|1,mid+1,r,x,val); pushup(o); } void pushup(int o){ maxv[o]=max(maxv[o<<1],maxv[o<<1|1]); } int query(int o,int l,int r,int q1,int q2){ if(q1<=l&&r<=q2){ return maxv[o]; } int ans=0; int mid=(l+r)>>1; if(q1<=mid)ans=max(ans,query(o<<1,l,mid,q1,q2)); if(q2>mid)ans=max(ans,query(o<<1|1,mid+1,r,q1,q2)); return ans; } }tree; void dfs(int u,int depth){ dep[u]=depth; num[u]=1; dfn[u]=++dfs_clock; int len=G[u].size(); for(int i=0;i<len;i++){ int v=G[u][i]; dfs(v,depth+1); num[u]+=num[v]; } } bool cmp(node A,node B){ return A.h<B.h; } bool cmp1(node A,node B){ return A.d<B.d; } int ans[maxn]; int main(){freopen("in.txt","r",stdin); int T; scanf("%d",&T); while(T--){ scanf("%d",&N); for(int i=0;i<=N;i++){ G[i].clear(); } for(int i=0;i<N;i++){ scanf("%d%d%d",&a[i].p,&a[i].h,&a[i].d); a[i].id=b[i].id=i; b[i].p=a[i].p; b[i].h=a[i].h; b[i].d=a[i].d; if(a[i].p!=-1)G[a[i].p].push_back(i); } dfs_clock=0; dfs(0,0); sort(a,a+N,cmp); sort(b,b+N,cmp1); tree.build(1,1,N); int j=0; for(int i=0;i<N;i++){ while(j<N&&a[j].h<=b[i].d){ tree.update(1,1,N,dfn[a[j].id],dep[a[j].id]); j++; } ans[b[i].id]=tree.query(1,1,N,dfn[b[i].id],dfn[b[i].id]+num[b[i].id]-1)-dep[b[i].id]; } for(int i=0;i<N;i++){ printf("%d",ans[i]); if(i==N-1)printf("\n"); else printf(" "); } } return 0; }

转载于:https://www.cnblogs.com/13224ACMer/p/4744350.html

2015暑假训练(UVALive 5983 - 5992)线段树离线处理+dp相关推荐

  1. HDU - 4417 Super Mario(主席树/线段树+离线)

    题目链接:点击查看 题目大意:给出由 n 个数的数列,再给出 m 次查询,每次查询需要输出 [ l , r ] 内小于等于 h 的数有多少个 题目分析:大晚上睡不着觉随便做做题,发现这个题目原来可以用 ...

  2. SPOJ - DQUERY D-query(莫队/线段树+离线/主席树)

    题目链接:点击查看 题目大意:给出一个由n个数组成的序列,再给出m次查询,每次查询区间[l,r]中有多少个不同的数 题目分析:莫队模板题,直接套板子就好了 有点意思的是函数返回值为布尔类型,然后没有r ...

  3. Super Mario HDU - 4417(主席树解决区间数字小于k的个数||线段树+离线)

    Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded in ...

  4. HDU 4417 Super Mario(线段树离线处理/主席树)

    Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded in ...

  5. COCI 2015/2016 PROKLETNIK(单调栈+线段树)

    COCI 2015/2016 PROKLETNIK 题目大意 给定序列A1..NA_{1..N}A1..N​,分别求出QQQ组询问区间[L,R][L,R][L,R]中最长的连续子序列Al..rA_{l ...

  6. 中石油训练赛 - Check List(线段树维护偏序问题)

    题目大意:给出 n 个点,需要计算出满足下列条件的三元对 ( i , j , k ) 的数量: x[ i ] < x[ j ] < x[ k ] y[ k ] > y[ i ] &g ...

  7. 蓝桥杯 ALGO-8 算法训练 操作格子(线段树)

    问题描述 有n个格子,从左到右放成一排,编号为1-n. 共有m次操作,有3种操作类型: 1.修改一个格子的权值, 2.求连续一段格子权值和, 3.求连续一段格子的最大值. 对于每个2.3操作输出你所求 ...

  8. 试题 算法训练 操作格子(线段树模板题)

    资源限制 内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s 问题描述 有n个格子,从左到右放成一排,编号为1-n. 共有m次操作,有3 ...

  9. UOJ#7. 【NOI2014】购票 | 线段树 凸包优化DP

    题目链接 UOJ #7 题解 首先这一定是DP!可以写出: \[f[i] = \min_{ancestor\ j} \{f[j] + (d[j] - d[i]) * p[i] + q[i]\}\] 其 ...

最新文章

  1. mysql必知必会看完看什么_《MySQL必知必会》读书笔记
  2. Jsp实现在线影院售票系统
  3. ubuntu 安装 phpstorm
  4. 信息系统项目管理师:论项目的沟通管理
  5. springboot 使用idea打包 遇到问题
  6. Spark Streaming 遇到 kafka
  7. rebots css,我的robots.txt中涉及到.htaccss文件的奇怪https/http错误
  8. Exchange 2010 无法删除第一个mailbox
  9. 空间相关分析(一) 空间权重矩阵
  10. 下载各种版本的weblogic
  11. 光环PMP:超凡IT经理人的“六重修炼”专题讲座
  12. 网易互娱的数据库选型和 TiDB 应用实践
  13. 从零開始搭建微信硬件开发环境全过程——1小时掌握微信硬件开发流程
  14. 计算机网络(HTTP协议 与 HTTPS)
  15. flac编码音频转alac编码(使用ffmpeg)
  16. I Incoming Asteroids(优先队列)
  17. 关于android的广告词,关于android:随心译无广告的专属实时翻译神器
  18. Keil5 安装使用
  19. php转存百度云盘,[转]Linux定时备份数据到百度云盘
  20. http://blog.sina.com.cn/s/blog_5da93c8f0102w86x.html

热门文章

  1. python数据分析基础教程 numpy_Python数据分析基础教程:NumPy学习指南(第2版)
  2. Chapter7-9_Deep Learning for Dependency Parsing
  3. LeetCode 1848. 到目标元素的最小距离
  4. LeetCode MySQL 1435. 制作会话柱状图
  5. LeetCode 819. 最常见的单词
  6. LeetCode 1418. 点菜展示表(哈希map)
  7. LeetCode 468. 验证IP地址
  8. python 类继承 父类初始化_python之子类继承父类时进行初始化的一些问题
  9. python 管理windows客户端_在远程windows客户端上执行python脚本
  10. php预处理_如何用预处理让 PHP 更先进