A.直接模拟。

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; ll n,k,T,ans; int main(){
for (cin>>T; T--; ){
cin>>n>>k; ans=;
for (ll x=n; x; x/=k,ans++) ans+=x%k;
cout<<ans-<<endl;
}
return ;
}

B.直接模拟,用栈记录下每层的循环次数,注意当总次数超过2^31时就直接记成2^31。

 #include<cstdio>
#include<algorithm>
#include<iostream>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=;
int T,top;
ll x,t,s[N]; int main(){
s[++top]=;
for (cin>>T; T--; ){
char op[]; cin>>op;
if (op[]=='f') cin>>t,top++,s[top]=(s[top-]<1ll<<)?t*s[top-]:s[top-];
else if (op[]=='e') top--; else x+=s[top];
if (x>=1ll<<){ cout<<"OVERFLOW!!!"<<endl; return ; }
}
cout<<x<<endl;
return ;
}

C.离一个点最近的k个点一定是一个区间,枚举每个长度为k的区间即可。

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=;
int n,k,T,ans,x,a[N]; int main(){
for (scanf("%d",&T); T--; ){
scanf("%d%d",&n,&k);
rep(i,,n) scanf("%d",&a[i]);
sort(a+,a+n+); ans=a[n]-a[]; x=a[];
rep(i,,n-k) if ((a[i+k]-a[i]+)/<ans) ans=(a[i+k]-a[i]+)/,x=(a[i]+a[i+k]+)/;
printf("%d\n",x);
}
return ;
}

D.每设一个断点相当于将贡献加上之后所有数的和,那么将所有后缀和放在一起排序,取贡献最小的几个断点即可。注意开头是一定要设断点的。

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=;
ll ans,sm[N];
int n,k,s,a[N],id[N],p[N];
bool cmp(int a,int b){ return sm[a]>sm[b]; } int main(){
scanf("%d%d",&n,&k);
rep(i,,n) scanf("%d",&a[i]);
for (int i=n; i; i--) sm[i]=sm[i+]+a[i],id[i]=i;
sort(id+,id+n+,cmp);
rep(i,,k) p[id[i]]=;
rep(i,,n){
if (p[i]) s++;
ans+=1ll*s*a[i];
}
cout<<ans<<endl;
return ;
}

E.倍增记录每个区间往后选2^i个区间最多能延伸到什么位置(保证这2^i个区间首尾不断),预处理的时候先按右端点排序,再用树状数组或者二分找到与当前区间首尾相接的右端点最靠右的区间。

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=;
int n,m,l,r,c[N],nxt[N][];
struct P{ int l,r; }p[N];
bool operator <(const P &a,const P &b){ return a.r>b.r; } int que(int x){ int res=; for (x++; x; x-=x&-x) if (p[c[x]].r>p[res].r) res=c[x]; return res; }
void add(int x,int k){ for (x++; x<=; x+=x&-x) if (p[c[x]].r<=p[k].r) c[x]=k; } int main(){
scanf("%d%d",&n,&m);
rep(i,,n) scanf("%d%d",&p[i].l,&p[i].r);
sort(p+,p+n+);
rep(i,,n) nxt[i][]=que(p[i].r),add(p[i].l,i);
rep(j,,) rep(i,,n) nxt[i][j]=nxt[nxt[i][j-]][j-];
rep(i,,m){
scanf("%d%d",&l,&r); int x=que(l),res=;
if (x==n+){ puts("-1"); continue; }
if (p[x].r>=r){ puts(""); continue; }
for (int i=; ~i; i--) if (nxt[x][i] && p[nxt[x][i]].r<r) res+=<<i,x=nxt[x][i];
res++; x=nxt[x][];
if (p[x].r<r) puts("-1"); else printf("%d\n",res);
}
return ;
}

F.考虑将条件转化:[l,r]值域是[1,r-l+1]等价于[l,r]区间内数两两不同且max(l,r)=r-l+1。首先我们对于每个位置i,可以轻易算出最大的r[i]使得[i,r[i]]中的数两两不同。根据max想到最值分治,然后发现每次遍历区间长度一定不大于min(mid-l,r-mid),于是就在O(nlogn)时间内解决了。

最值分治大概就是,对于当前考虑区间[l,r]找到其中最大/小的数a[mid],然后对[l,mid-1]和[mid+1,r]分别递归下去。合并时,只遍历短的那一边,计算短的那一边的每个数与长的那一边整体产生的贡献。复杂度类比启发式合并可知显然为O(nlogn)。这题中就是每次找到最大值a[mid],然后计算有多少跨过mid的合法区间,根据之前的r[i]数组可以轻松得到答案。

 #include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=;
int n,ans,a[N],b[N],lst[N],lg[N],st[N][]; int Max(int x,int y){ return a[x]>a[y] ? x : y; } int que(int l,int r){ int t=lg[r-l+]; return Max(st[l][t],st[r-(<<t)+][t]); } void work(int l,int r){
int mid=que(l,r);
rep(i,max(l,mid-a[mid]+),min(mid,r-a[mid]+)) if (b[i]>=a[mid]) ans++;
if (l<mid) work(l,mid-);
if (r>mid) work(mid+,r);
} int main(){
scanf("%d",&n);
rep(i,,n) scanf("%d",&a[i]),st[i][]=i;
b[n+]=n+; rep(i,,n) lst[i]=n+;
for (int i=n; i; i--) b[i]=min(b[i+]+,lst[a[i]]-i),lst[a[i]]=i;
rep(i,,n) lg[i]=lg[i>>]+;
rep(j,,lg[n]) rep(i,,n-(<<j)+) st[i][j]=Max(st[i][j-],st[i+(<<(j-))][j-]);
work(,n); printf("%d\n",ans);
return ;
}

G.一个显然的DP是,f[i][j]表示前i个数分j段的最小总和,转移枚举第j段的开头,复杂度O(kn^2)。考虑对每个j做类似CDQ分治,先递归算出[l,mid]和[mid+1,r]两个区间的答案,再计算[mid+1,r]中的每个位置的最后一段开头在[l,mid]中时,能否更新答案。我们从mid开始向前向后分别求后缀和与前缀和,然后分“最后一段的最大值在[l,mid]还是[mid+1,r]”两种情况转移,发现方程是一个关于前缀后缀和的一个一次函数。于是问题变为,分治后在线往直线集中加入一条新直线,并实时查询集合中所有直线某个横坐标上的值的最大值。用单调栈维护一个上凸壳,查询时二分即可。注意一个细节是,当新加入的直线斜率和上一条直线斜率相同时,普通的计算交点方法就错了。于是复杂度为O(nklogn)。

 #include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=,inf=1e9;
int n,k,top,a[N],f[N],g[N],pre[N],suf[N];
struct L{ int k,b; int F(int x){ return k*x+b; } }q[N]; bool cmp(L a,L b,L c){ return 1ll*(a.k-b.k)*(c.b-a.b)<=1ll*(a.k-c.k)*(b.b-a.b); } void ins(L x){
while (top && x.k>=q[top].k) x.b=min(x.b,q[top].b),top--;
while (top> && cmp(q[top-],q[top],x)) top--;
q[++top]=x;
} int calc(int x){
if (!top) return inf;
int l=,r=top;
while (l<r){
int mid=(l+r)>>;
if (q[mid].F(x)<=q[mid+].F(x)) r=mid; else l=mid+;
}
return q[l].F(x);
} void solve(int l,int r){
if (l==r) return;
int mid=(l+r)>>;
solve(l,mid); solve(mid+,r);
suf[mid+]=; for (int i=mid; i>=l; i--) suf[i]=max(suf[i+],a[i]);
pre[mid]=; rep(i,mid+,r) pre[i]=max(pre[i-],a[i]);
top=;
for (int i=r,j=l; i>mid; i--){
while (j<=mid && suf[j+]>=pre[i]) if (g[j++]<inf) ins((L){suf[j],g[j-]-(j-)*suf[j]});
f[i]=min(f[i],calc(i));
}
top=;
for (int i=mid+,j=mid; i<=r; i++){
while (j>=l && suf[j+]<=pre[i]) if (g[j--]<inf) ins((L){j+,g[j+]});
f[i]=min(f[i],calc(-pre[i])+i*pre[i]);
}
} int main(){
scanf("%d%d",&n,&k);
rep(i,,n) scanf("%d",&a[i]),pre[i]=max(pre[i-],a[i]);
rep(i,,n) f[i]=pre[i]*i;
rep(i,,k){
rep(j,,n) g[j]=f[j],f[j]=inf;
solve(,n);
}
printf("%d\n",f[n]);
return ;
}

Educational Codeforces Round 66 (Rated for Div. 2)的更多相关文章

  1. Educational Codeforces Round 66 (Rated for Div. 2) B. Catch Overflow!

    链接:https://codeforces.com/contest/1175/problem/B 题意: You are given a function ff written in some bas ...

  2. Educational Codeforces Round 66 (Rated for Div. 2) A. From Hero to Zero

    链接:https://codeforces.com/contest/1175/problem/A 题意: You are given an integer nn and an integer kk. ...

  3. Educational Codeforces Round 66 (Rated for Div. 2) A

    A. From Hero to Zero 题目链接:http://codeforces.com/contest/1175/problem/A 题目 ou are given an integer n ...

  4. Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship Time Limit: 2000 mSec P ...

  5. Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems Time Limit: 3000 mSec P ...

  6. Educational Codeforces Round 43 (Rated for Div. 2)

    Educational Codeforces Round 43 (Rated for Div. 2) https://codeforces.com/contest/976 A #include< ...

  7. Educational Codeforces Round 35 (Rated for Div. 2)

    Educational Codeforces Round 35 (Rated for Div. 2) https://codeforces.com/contest/911 A 模拟 #include& ...

  8. Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings

    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings 题目连接: http://cod ...

  9. Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes

    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes 题目连接: http://code ...

随机推荐

  1. 【loj3045】【ZJOI2019】开关

    题目 \(n\)个开关,一开始处于关闭状态,你需要将他们按成\(s\)状态,按成了之后就停止操作; 每次按下开关的i概率为\(\frac{p_i}{\sum_{i=1}^{n}p_i}\) ,问期望步 ...

  2. 使用jstack命令查看CPU高占用的问题记录

    笔记: 1.top命令找出最高占用的进程(command为java) 2.查看高负载进程下的高负载线程:top -Hp [PID] (或 ps -mp PID -o THREAD,tid,time) ...

  3. UOJ46. 【清华集训2014】玄学 [线段树,二进制分组]

    UOJ 思路 模拟赛出了这题,结果我没学过二进制分组--一波主席树然后空间就爆炸了-- 用线段树维护时间序列,每个节点维护\(a_i\to x_i\times a_i+b_i,i\in [1,n]\) ...

  4. Nginx压测和并发预估

    一.Nginx并发预估 预估算法:{(?G)*1024-system}/请求大小 (?G):表示内存大小1024:表示内存容量标准进制system:表示系统和服务占用的额外内存和需要预留的内存请求大小 ...

  5. <英狼>--团队作业3 王者光耀--终极版

    队员 陶俊宇_031702113 卞永亨_031702229 唐怡_031702109 Github 吉哈---King-Shines 队员输出百分比,数据为估值仅供参考 MVP:队长:陶俊宇 60% ...

  6. linux core 性能

    apt-get install lrzsz apt-get install vim apt-get install -y net-tools apt-get install -y procps htt ...

  7. The fileSyncDll.ps1 is not digitally signed. You cannot run this script on the current system.

    https://www.opentechguides.com/how-to/article/powershell/105/powershel-security-error.html Unblockin ...

  8. dubbo、zookeeper心跳相关参数解析与测试

    dubbo consumer和provider的心跳机制 dubbo客户端和dubbo服务端之间存在心跳,目的是维持provider和consumer之间的长连接.由dubbo客户端主动发起,可参见d ...

  9. jq select change下拉框选项变化判断选中值,添加(attr)或移除(removeAttr)一个或多个属性

    select change下拉框选项变化判断选中值,添加(attr)或移除(removeAttr)一个或多个属性 $("#IsRecommend").change(function ...

  10. 004 vue组件

    一:创建组件 1.第一种创建方式 主要有Vue.extend,Vue.component. 注释掉的代码是一步一步的推断,后面的代码是简化的代码. <!DOCTYPE html> < ...