2016-浙江理工新生赛-部分题解
来源:互联网 发布:糖果屋淘宝 编辑:程序博客网 时间:2024/04/29 21:53
巴比伦花园
link :http://oj.acm.zstu.edu.cn/JudgeOnline/problem.php?id=4239
对于新生还是比较难;
我是用 RMQ + 二分 写的; 因为 fi[i] 数组代表从i开始最长到哪里,因为要求最长,所以第一个一定是1, i 是单调的,fi 数组也是单调的,所以可以二分;二分找刚刚在区间的,完全在区间用RMQ 离线查询;
#include <cstdio>#include <cstring>#include <cctype>#include <cmath>#include <set>#include <map>#include <list>#include <queue>#include <deque>#include <stack>#include <string>#include <vector>#include <iostream>#include <algorithm>#include <stdlib.h>#include <time.h> using namespace std;typedef long long LL;const int INF=2e9+1e8;const int MOD=1e9+7;const int MAXSIZE=1e6+5;const double eps=0.0000000001;void fre(){ freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}#define memst(a,b) memset(a,b,sizeof(a))#define fr(i,a,n) for(int i=a;i<n;i++) const int MAXN=1e5+10;int n,k,q;LL input[MAXN];int fi[MAXN];struct RMQ{int dp[MAXN][20];void init() { for(int i=1;i<=n;i++) dp[i][0]=fi[i]; for(int i=1;i<20;i++) for(int j=1;j<=n;j++) if(j+(1<<i)-1<=n) dp[j][i]=max(dp[j][i-1],dp[j+(1<<(i-1))][i-1]); } int query(int l,int r) { if(l>r) return -1; if(l==r) return fi[l]; int _k=(int)log2(r-l+1); return max(dp[l][_k],dp[r-(1<<_k)+1][_k]); }}rmq;int query(int l,int st){for(int i=l;i<=n;i++)if(input[i]<1+k*((LL)i-st)) return i-st;return n-st+1;}int findR(int L,int R,int& b){int l=1,r=n;while(1){int mid=(l+r)>>1;if(fi[mid]+mid-1>=R&&fi[mid-1]+mid-2<R) {b=mid-1;return R-max(L,mid)+1;}if(fi[mid]+mid-1>=R) r=mid;else l=mid+1;}}int findL(int L,int R,int& a){int l=1,r=n;while(1){int mid=(l+r)>>1;if(mid<=L&&mid+1>L) {a=mid+1;return min(R,mid+fi[mid]-1)-L+1;}if(mid<=L) l=mid+1;else r=mid;}}int main(){int ncase;scanf("%d",&ncase);while(ncase--){scanf("%d%d%d",&n,&k,&q);fi[0]=-INF;for(int i=1;i<=n;i++)scanf("%lld",&input[i]);for(int i=1;i<=n;i++)fi[i]=query(max(i-1+fi[i-1],i),i); fi[n+1]=INF;rmq.init();while(q--){int l,r,a,b;scanf("%d%d",&l,&r);int maxnum=max(findL(l,r,a),findR(l,r,b));printf("%d\n",max(rmq.query(a,b),maxnum));}}return 0;}/**************************************************//** Copyright Notice **//** writer: wurong **//** school: nyist **//** blog : http://blog.csdn.net/wr_technology **//**************************************************/
D 题也是同一种套路; RMQ + 二分
4241: 圣杯战争
#include <cstdio>#include <cstring>#include <cctype>#include <cmath>#include <set>#include <map>#include <list>#include <queue>#include <deque>#include <stack>#include <string>#include <vector>#include <iostream>#include <algorithm>#include <stdlib.h>#include <time.h>using namespace std;typedef long long LL;const int INF=2e9+1e8;const int MOD=1e9+7;const int MAXSIZE=1e6+5;const double eps=0.0000000001;void fre(){ freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}#define memst(a,b) memset(a,b,sizeof(a))#define fr(i,a,n) for(int i=a;i<n;i++)const int MAXN=2e5+10;int n,m,q,total,ans;LL atk[MAXN],presum[MAXN];int ap[MAXN],pos[MAXN];pair<int,int> seg[MAXN],Interval[MAXN];struct RMQ{int dp[MAXN][20];void init() { for(int i=1;i<total;i++) dp[i][0]=Interval[i].second-Interval[i].first+1; for(int i=1;i<20;i++) for(int j=1;j<total;j++) if(j+(1<<i)-1<total) dp[j][i]=max(dp[j][i-1],dp[j+(1<<(i-1))][i-1]); } int query(int l,int r) { if(l>r) return 0; int _k=(int)log2(r-l+1); return max(dp[l][_k],dp[r-(1<<_k)+1][_k]); }}rmq;bool cmp(pair<int,int> a,pair<int,int> b)//按照 first 从小到大,first 一样的按照 second 的从大到小{ if(a.first!=b.first) return a.first<b.first; else return a.second>b.second;}bool cmp1(pair<int,int> a,int val){ return a.first<val;}bool cmp2(pair<int,int> a,int val){ return a.second<val;}int query(int l,int r){ l=l^ans,r=r^ans; if(l>r) swap(l,r); l=max(1,l),r=min(n,r); // printf("query %d %d\n",l,r); int fl,fr,maxnum; fl=lower_bound(Interval+1,Interval+total,l,cmp1)-Interval-1; fr=lower_bound(Interval+1,Interval+total,r,cmp2)-Interval; // int ans1=min(Interval[fl].second,r)-max(l,Interval[fl].first)+1; int ans2=min(r,Interval[fr].second)-max(l,Interval[fr].first)+1; if(fl>=total||fl<=0) ans1=-1; if(fr>=total||fr<=0) ans2=-1; maxnum=max(ans1,ans2); // printf("ans= %d %d %d\n",ans1,ans2,rmq.query(fl+1,fr-1)); return max(rmq.query(fl+1,fr-1),maxnum);}void debug(int k){// for(int i=0;i<k;i++)// printf("seg[%d] : %d %d\n",i,seg[i].first,seg[i].second);// printf("\n***********************************\n"); printf("total=%d\n",total); for(int i=1;i<total;i++) printf("seg[%d] : %d %d\n",i,Interval[i].first,Interval[i].second); printf("\n***********************************\n");}LL getval(int l,int r){ return presum[r]-presum[l-1];}int Lpos(int _pos,int _ap){ int l=1,r=_pos; while(1) { int mid=(l+r)>>1; if((mid==1&&getval(mid,_pos)<=_ap)||(getval(mid,_pos)<=_ap&&getval(mid-1,_pos)>_ap)) return mid; if(getval(mid,_pos)<=_ap) r=mid; else l=mid+1; }}int Rpos(int _pos,int _ap){ int l=_pos,r=n; while(1) { int mid=(l+r)>>1; if((mid==n&&getval(_pos,mid)<=_ap)||(getval(_pos,mid)<=_ap&&getval(_pos,mid+1)>_ap)) return mid; if(getval(_pos,mid)<=_ap) l=mid+1; else r=mid; }}int main(){int ncase;scanf("%d",&ncase);while(ncase--){scanf("%d%d%d",&n,&m,&q);presum[0]=0;for(int i=1;i<=n;i++){scanf("%lld",&atk[i]);presum[i]=atk[i]+presum[i-1];}for(int i=0;i<m;i++)scanf("%d",&pos[i]);for(int i=0;i<m;i++)scanf("%d",&ap[i]);int k=0; presum[n+1]=INF;for(int i=0;i<m;i++){if(ap[i]<atk[pos[i]]) continue;seg[k].first=Lpos(pos[i],ap[i]),seg[k++].second=pos[i];seg[k].first=pos[i],seg[k++].second=Rpos(pos[i],ap[i]);}// OK;if(k==0) { int l,r; while(q--) scanf("%d%d",&l,&r),printf("0\n"); continue; }sort(seg,seg+k,cmp);//OK;total=2;Interval[1]=seg[0];for(int i=1;i<k;i++) if(seg[i].second>Interval[total-1].second) Interval[total++]=seg[i]; rmq.init(); Interval[0].first=Interval[0].second=-1; Interval[total].first=Interval[total].second=INF; ans=0; // debug(k); while(q--) { int l,r; scanf("%d%d",&l,&r); printf("%d\n",ans=query(l,r)); }}return 0;}/**************************************************//** Copyright Notice **//** writer: wurong **//** school: nyist **//** blog : http://blog.csdn.net/wr_technology **//**************************************************/
4248: KI的目标
/*如果 dis(a,b)>=val[a]-val[b] && dis[b,c]>=val[b]-val[c];那么 dis(a,c)>=val[a]-val[c];所以 只需要判断 val[现在的点]-val[下一个点]>边权值 如果真就不统计;*/#include <cstdio>#include <cstring>#include <cctype>#include <cmath>#include <set>#include <map>#include <list>#include <queue>#include <deque>#include <stack>#include <string>#include <vector>#include <iostream>#include <algorithm>#include <stdlib.h>#include <time.h>using namespace std;typedef long long LL;const int INF=2e9+1e8;const int MOD=1e9+7;const int MAXSIZE=1e6+5;const double eps=0.0000000001;void fre(){ freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}#define memst(a,b) memset(a,b,sizeof(a))#define fr(i,a,n) for(int i=a;i<n;i++)const int MAXN = 1000000+10;struct Node{ int to,next,val;}edge[MAXN<<1];int first[MAXN],ntot;void init(){ ntot=0; memset(first,-1,sizeof(first));}void addedge(int s,int t,int val){ edge[ntot].to=t,edge[ntot].val=val; edge[ntot].next=first[s]; first[s]=ntot++;}int val[MAXN];int n;int dfs (int o,int now){ int res=1; for (int i=first[now],to,value; ~i; i=edge[i].next) { to=edge[i].to, value=edge[i].val; if (to==o) continue; if (val[now]-val[to]>value) //val(v)<val(u)+path(u)-Path(v) 那么val(u)+path(u)取最大 { continue; } res += dfs (now, to); } return res;}int main (){ int ncase; scanf ("%d", &ncase); while(ncase--) { scanf ("%d", &n); init(); for (int i=1,u,v,w; i<n; i++) { scanf ("%d%d%d", &u, &v, &w); addedge(u,v,w); addedge(v,u,w); } for (int i=1; i<=n; i++) scanf ("%d", val+i); printf ("%d\n", dfs (1, 1)); } return 0;}/**************************************************//** Copyright Notice **//** writer: wurong **//** school: nyist **//** blog : http://blog.csdn.net/wr_technology **//**************************************************/
0 0
- 2016-浙江理工新生赛-部分题解
- 本次新生赛部分题解
- 2016年3月浙江理工大学校赛E 题解
- 浙江理工校赛
- ZSTU-4242-校庆【浙江理工2016全国新生邀请赛E题】
- 2015广东工业大学新生赛 总结+部分题解
- 【浙江理工大学2016年新生赛暨全国新生邀请赛】 J 萌新吃果果,ZSTUOJ 4286【模拟】
- 2017年浙江理工大学新生赛
- 题解 广东工业大学 新生赛 2016-12-04
- BNUOJ新生赛题解
- GPNU2017新生赛题解
- 17新生测试大题部分 题解
- 浙江理工大学2016年新生赛暨全国新生邀请赛H ZSTUOJ 4245: KI的斐波那契
- 【浙江理工大学2016年新生赛暨全国新生邀请赛】 F 牛吃草,ZSTUOJ4243 【计算几何+二分】
- 【浙江理工大学2016年新生赛暨全国新生邀请赛】 E 校庆 ZSTUPJ4242 【坑爹的日期计算】
- 【浙江理工大学2016年新生赛暨全国新生邀请赛】 A,Save the Princess,ZSTUOJ 4238【博弈?】
- 哈理工新生赛热身赛解题报告
- 浙江理工3881
- 浅析抽象类与接口
- 免费网络存储
- Laravel-dingo/api获取路由
- java中匿名内部类的理解
- 第12周课后实践 多文件组织
- 2016-浙江理工新生赛-部分题解
- Git自动化部署
- 函数调用栈帧结构
- yii 2.0 常用表单(yii\widgets\ActiveField)
- 数组和指针的一个例子
- 简单工厂模式
- JDBC
- Android 中非UI线程真的不能更新UI吗?
- 神经网络ANN分类器及OpenCV实现