A.求两个时间比较一下。

#include<bits/stdc++.h>
using namespace std; int n,t,k,d; int main()
{
ios::sync_with_stdio(false);
cin >> n >> t >> k >> d;
int tt = n/k;
if(n%k) tt++;
int sum1 = tt*t;
int t1 = ,t2 = d,now = ;
while(now < tt)
{
if(t1 < t2) t1 += t;
else t2 += t;
now++;
}
int sum2 = max(t1,t2);
if(sum1 > sum2) cout << "YES" << endl;
else cout << "NO" << endl;
return ;
}

B.按价格排序,预记录每种颜色的位置,询问的时候保存前一个可行的位置,线性扫即可。

#include<bits/stdc++.h>
using namespace std; int n,m,pos[][],ok[] = {};
struct xx
{
int p,a,b;
friend bool operator <(xx a,xx b)
{
return a.p < b.p;
}
}a[]; int main()
{
ios::sync_with_stdio(false);
cin >> n;
for(int i = ;i <= n;i++) cin >> a[i].p;
for(int i = ;i <= n;i++) cin >> a[i].a;
for(int i = ;i <= n;i++) cin >> a[i].b;
sort(a+,a++n);
int cnt[] = {};
for(int i = ;i <= n;i++)
{
int x = a[i].a,y = a[i].b;
pos[x][++cnt[x]] = i;
if(x != y) pos[y][++cnt[y]] = i;
}
cin >> m;
int now[] = {,,,,};
while(m--)
{
int x;
cin >> x;
while(ok[pos[x][now[x]]]) now[x]++;
if(now[x] > cnt[x]) cout << - << " ";
else
{
ok[pos[x][now[x]]] = ;
cout << a[pos[x][now[x]]].p << " ";
}
}
return ;
}

C.分三种情况

1.两堆各取一个,直接遍历取每堆的符合要求的最大b值。

2.在A堆取2个。先按p小到大排序,然后从头到尾枚举一个c,二分符合要求的c-p值最后一个的位置,在这一段rmq找最大的b值,更新最大的和。

3.在B堆取2个,同上。

#include<bits/stdc++.h>
using namespace std; int n,c,d;
int maxdp1[][],maxdp2[][];
struct xx
{
int b,x;
xx(){};
xx(int bb,int xx):b(bb),x(xx){};
friend bool operator <(xx a,xx b)
{
return a.x < b.x;
}
}a[],b[]; void rmq_init1(int len)
{
for(int i = ;i <= len;i++) maxdp1[i][] = a[i].b;
for(int j = ;(<<j) <= len;j++)
{
for(int i = ;i+(<<j)- <= len;i++)
{
maxdp1[i][j] = max(maxdp1[i][j-],maxdp1[i+(<<(j-))][j-]);
}
}
} void rmq_init2(int len)
{
for(int i = ;i <= len;i++) maxdp2[i][] = b[i].b;
for(int j = ;(<<j) <= len;j++)
{
for(int i = ;i+(<<j)- <= len;i++)
{
maxdp2[i][j] = max(maxdp2[i][j-],maxdp2[i+(<<(j-))][j-]);
}
}
} int rmq_max1(int l,int r)
{
int k = (int)(log((double)(r-l+))/log(2.0));
return max(maxdp1[l][k],maxdp1[r-(<<k)+][k]);
} int rmq_max2(int l,int r)
{
int k = (int)(log((double)(r-l+))/log(2.0));
return max(maxdp2[l][k],maxdp2[r-(<<k)+][k]);
} int main()
{
ios::sync_with_stdio(false);
cin >> n >> c >> d;
int cnt1 = ,cnt2 = ;
for(int i = ;i <= n;i++)
{
int x,y;
string s;
cin >> x >> y >> s;
if(s == "C")
{
a[++cnt1].b = x;
a[cnt1].x = y;
}
else
{
b[++cnt2].b = x;
b[cnt2].x = y;
}
}
int maxx = ;
int pos1 = -,max1 = ;
for(int i = ;i <= cnt1;i++)
{
if(a[i].x <= c && a[i].b > max1)
{
pos1 = i;
max1 = a[i].b;
}
}
int pos2 = -,max2 = ;
for(int i = ;i <= cnt2;i++)
{
if(b[i].x <= d && b[i].b > max2)
{
pos2 = i;
max2 = b[i].b;
}
}
if(pos1 != - && pos2 != -) maxx = max1+max2;
sort(a+,a++cnt1);
sort(b+,b++cnt2);
rmq_init1(cnt1);
rmq_init2(cnt2);
if(cnt1 > && a[].x+a[].x <= c)
{
for(int i = ;i <= cnt1;i++)
{
if(a[i].x >= c) break;
int t = upper_bound(a+,a+cnt1+,xx(,c-a[i].x))-a-;
if(t <= i) break;
maxx = max(maxx,a[i].b+rmq_max1(i+,t));
}
}
if(cnt2 > && b[].x+b[].x <= d)
{
for(int i = ;i <= cnt2;i++)
{
if(b[i].x >= d) break;
int t = upper_bound(b+,b+cnt2+,xx(,d-b[i].x))-b-;
if(t <= i) break;
maxx = max(maxx,b[i].b+rmq_max2(i+,t));
}
}
cout << maxx << endl;
return ;
}

还有一种方法,直接树状数组维护最大前缀max。

#include <bits/stdc++.h>
using namespace std; int n,c,d,C[],D[]; inline int lowbit(int x)
{
return x & (-x);
} void update(int tree[],int pos,int x)
{
while(pos <= )
{
tree[pos] = max(tree[pos],x);
pos += lowbit(pos);
}
} int getmax(int tree[],int pos)
{
int ans = INT_MIN;
while(pos > )
{
ans = max(ans,tree[pos]);
pos -= lowbit(pos);
}
return ans;
} int main()
{
ios::sync_with_stdio(false);
cin >> n >> c >> d;
for(int i = ;i <= ;i++)
{
C[i] = INT_MIN;
D[i] = INT_MIN;
}
int ans = ;
while(n--)
{
int b,p,t;
string s;
cin >> b >> p >> s;
if(s == "C")
{
if(p > c) continue;
t = max(getmax(C,c-p),getmax(D,d));
update(C,p,b);
}
else
{
if(p > d) continue;
t = max(getmax(C,c),getmax(D,d-p));
update(D,p,b);
}
ans = max(ans,t+b);
}
cout << ans << endl;
return ;
}

D.边长指数增长,我们需要的倍数很少,直接爆搜就可以了。

#include <bits/stdc++.h>
using namespace std; int a,b,w,h,n,A[],ans; void dfs(int x,int y,int now,int nowx,int nowy)
{
if(nowx >= x && nowy >= y)
{
ans = min(ans,now);
return;
}
if(now == n+) return;
if(A[now] == )
{
while(x > nowx)
{
nowx *= ;
now++;
}
while(y > nowy)
{
nowy *= ;
now++;
}
ans = min(ans,now);
return; }
if(x > nowx) dfs(x,y,now+,nowx*A[now+],nowy);
if(y > nowy) dfs(x,y,now+,nowx,nowy*A[now+]);
}
int main()
{
ios::sync_with_stdio(false);
cin >> a >> b >> w >> h >> n;
for(int i = ;i <= n;i++) cin >> A[i];
sort(A+,A++n);
reverse(A+,A++n);
ans = n+;
dfs((a-)/h+,(b-)/w+,,,);
dfs((a-)/w+,(b-)/h+,,,);
if(ans == n+) cout << - << endl;
else cout << ans << endl;
return ;
}

E.把原数组分为4类,①A、M都不喜欢v0。②A喜欢、M不喜欢。③A不喜欢、M喜欢。④A、M都喜欢。

我们枚举④中的数量,然后计算剩余②③中最少数量,剩下的数从①②③中小的挑出。

枚举④的数量从大到小,这样②③个数肯定是递增的,因此就能使用上一次保存②③的个数。

#include<bits/stdc++.h>
using namespace std; int n,m,k,a[];
int v0[],v1[],v2[],v3[];
long long sum0[] = {},sum1[] = {},sum2[] = {},sum3[] = {};
bool has1[] = {},has2[] = {}; int main()
{
ios::sync_with_stdio(false);
cin >> n >> m >> k;
for(int i = ;i <= n;i++) cin >> a[i];
int x;
cin >> x;
while(x--)
{
int xx;
cin >> xx;
has1[xx] = ;
}
cin >> x;
while(x--)
{
int xx;
cin >> xx;
has2[xx] = ;
}
int cnt0 = ,cnt1 = ,cnt2 = ,cnt3 = ;
for(int i = ;i <= n;i++)
{
if(has1[i] && has2[i]) v3[++cnt3] = a[i];
else if(has1[i]) v1[++cnt1] = a[i];
else if(has2[i]) v2[++cnt2] = a[i];
else v0[++cnt0] = a[i];
}
sort(v0+,v0++cnt0);
sort(v1+,v1++cnt1);
sort(v2+,v2++cnt2);
sort(v3+,v3++cnt3);
for(int i = ;i <= cnt0;i++) sum0[i] = sum0[i-]+v0[i];
for(int i = ;i <= cnt1;i++) sum1[i] = sum1[i-]+v1[i];
for(int i = ;i <= cnt2;i++) sum2[i] = sum2[i-]+v2[i];
for(int i = ;i <= cnt3;i++) sum3[i] = sum3[i-]+v3[i];
long long ans = 1e18;
int t1 = ,t2 = ;
for(int i = min(cnt3,m);i >= ;i--)
{
t1 = max(t1,k-i),t2 = max(t2,k-i);
if(t1+t2+i > m || t1 > cnt1 || t2 > cnt2) break;
if(cnt0+cnt1+cnt2+i < m) break;
int t0 = ;
while(t0+t1+t2+i < m)
{
int t = m-t1-t2-i;
if(cnt0 >= t && (t1 == cnt1 || v0[t] <= v1[t1+]) && (t2 == cnt2 || v0[t] <= v2[t2+])) {t0 = t;break;}
else if(t1 < cnt1 && (t2 == cnt2 || v1[t1+] <= v2[t2+])) t1++;
else t2++;
}
ans = min(ans,sum0[t0]+sum1[t1]+sum2[t2]+sum3[i]);
}
if(ans == 1e18) cout << - << endl;
else cout << ans << endl;
return ;
}

Codeforces_799的更多相关文章

随机推荐

  1. 还在使用OpenGL ES做渲染,你Out了,赶紧来拥抱Vulkan吧~

    背景介绍 Vulkan是Khronos组织制定的"下一代"开放的图形显示API.是与DirectX12能够匹敌的GPU API标准. Vulkan是基于AMD的Mantle API ...

  2. 《图解机器学习-杉山将著》读书笔记---CH5

    CH5 稀疏学习 重点提炼 提出稀疏学习的缘故: 虽然带有约束条件的最小二乘学习法结合交叉验证法,在实际应用中是非常有效的回归方法,但是,当参数特别多时,计算参数以及预测值需要大量时间.此时,我们要解 ...

  3. Anaconda----Python的计算环境

    由于要用到opencv中的cv2这个module,我会在Anaconda这个Python的计算环境中安装加入opencv. 打开一个终端,输入: conda install opencv 显示: 选择 ...

  4. 【Javascript函数】节流throttle和间隔控制dbounce

    一.throttle 函数节流,指把很小时间内触发的N多事件,节流成1个事件. 我们这里说的throttle就是函数节流的意思.再说的通俗一点就是函数调用的频度控制器,是连续执行时间间隔控制.主要应用 ...

  5. 2020 年了,Java 日志框架到底哪个性能好?——技术选型篇

    大家好,之前写(shui)了两篇其他类型的文章,感觉大家反响不是很好,于是我乖乖的回来更新硬核技术文了. 经过本系列前两篇文章我们了解到日志框架大战随着 SLF4j 的一统天下而落下帷幕,但 SLF4 ...

  6. acmPush模块示例demo

    感谢论坛版主 马浩川 的分享. 模块介绍:  阿里移动推送(Alibaba Cloud Mobile Push)是基于大数据的移动智能推送服务,帮助App快速集成移动推送的功能,在实现高效.精确.实时 ...

  7. Java 使用Scanner时的NoSuchElementException异常

    做实验时设计了一个类,在类中的两个不同函数中分别创建了两个Scanner对象,并且在各个函数的结尾使用了close()方法,结果在运行时产生了NoSuchElementException异常. 实验的 ...

  8. B-Tree 和 B+Tree 结构及应用,InnoDB 引擎, MyISAM 引擎

    1.什么是B-Tree 和 B+Tree,他们是做什么用的? B-Tree是为了磁盘或其它存储设备而设计的一种多叉平衡查找树,B-Tree 和 B+Tree 广泛应用于文件存储系统以及数据库系统中. ...

  9. redis server can not continue

  10. PHP 1-16课

    浏览器      使用火狐浏览器 认识标签 个人使用的编辑器:HbuilderX 标签是HTML5的基本结构,标签分为双标签和单标签 例如:<li> </li> <br ...