A. Sweet Problem (找规律)

题目链接

大致思路:

有一点瞎猜的,首先排一个序, \(a_1>a_2>a_3\) ,发现如果 \(a_1>=a_2+a_3\) ,那么答案肯定是 \(a_2+a_3\) ,然后发现发现规律当 \(a_2==a_3\) 的时候,还可以贡献 \((a_1+a_2+a_3)/2\) 的答案,所以只要 \(a_1\) 和 \(a_2\) 减掉一个值就可以了。

B. PIN Codes (暴力)

题目链接

大致思路:

可以知道,存在一个数字不同的pin是大于100个的,那么只要将所有的pin用map记录一下,把出现重复的暴力改数字改到不重复为止就行了。要注意不能边读入边改,这样可能会改成和后面的一样导致答案变大。

C. Everyone is a Winner! (数学)

题目链接

大致思路:

主要使用到除法分块,因为用计算器计算整数除法,会存在 \([a,b]\) 的数除上 \(i\) 的值的相同,我们可以用 \(\sqrt{n}\) 的复杂度求出,是一个模板题。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int T;
int ans[N];
int main()
{ //freopen("H:\\c++1\\in.txt","r",stdin);
//freopen("H:\\c++1\\out.txt","w",stdout);
scanf("%d",&T);
int n;
while(T--){
int cnt=0;
scanf("%d",&n);
for(int l=1,r;l<=n;l=r+1)
{
r=n/(n/l);
//cout<<l<<" "<<r<<endl;
ans[++cnt]=r;
//ans+=(r-l+1)*(n/l);
}
sort(ans+1,ans+cnt+1);
printf("%d\n",cnt+1);
for(int i=0;i<=cnt;i++){
printf("%d%c",ans[i],i==cnt?'\n':' ');
}
}
return 0;
}

D. Secret Passwords (并查集/瞎搞)

题目链接

题目大意:

给 \(n\) 个字符串,两个字符串为一类的条件是存在一个相同的字母,问 \(n\) 个字符串可以分成几类。

大致思路:

比赛的时候是瞎做的,对每一字母进行考虑,不断增大答案的集合,假设当前到来第 \(i\) 个字母,如果字符串如果还没被标记那么它不存在 \([1,i]\) 字母,必然不能影响前面的分类结果。

或者使用并查集用字母来分类,写起来很简单。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
string s[N];
bool gs[N][26];
int jl[N];
bool vis[N];
int n;
queue<int>q;
int main()
{
//freopen("H:\\c++1\\in.txt","r",stdin);
//freopen("H:\\c++1\\out.txt","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++){
cin>>s[i];
int len=s[i].length();
for(int j=0;j<len;j++){
gs[i][s[i][j]-'a']=1;
}
}
int id=0;
for(int i=1;i<=n;i++){
for(int j=0;j<26;j++){
if(gs[i][j])jl[i]|=(1<<j),id=j;
}
}
int now=0;
for(int i=1;i<=n;i++){
if((jl[i]>>id)&1){
now|=jl[i];
vis[i]=1;
}
}
int ans=1;
for(int i=0;i<26;i++)
if(((now>>i)&1)==0){
for(int j=1;j<=n;j++)
if(vis[j]==0&&((jl[j]>>i)&1)){
if((jl[j]&now)==0){
ans++;
}
now|=jl[j];
vis[j]=1;
}
}
cout<<ans<<endl;
return 0;
}

E. Editor (线段树)

题目链接

题目大意:

给一个按键序列,其中有 \((),R,L\) ,字母,通过 \(R\) 和 \(L\) 来移动编辑的光标,每次指令输出当前序列的括号是否合法,若合法输出最大嵌套数量。

大致思路:

观察一个括号序列, \((()()())()\) ,如果我们将 \((\) 做为 \(,1,)\) 括号做为 \(-1\) ,得到前缀和序列 \(1,2,1,2,1,2,1,0,1,0\) ,那么如果当前括号合法,那么其最后的前缀和为 \(0\) ,且前缀和序列最小值大于等于 \(0\),那么我们就可以模拟指令的输入,对于一个括号,就是对 \(正无穷(pos,正无穷)\) 的一个区间加,然后最大的嵌套次数就是区间的最大值,用区间最小值来判断合法即可,用线段树来维护,要注意会出现 \(pos=1\), 还有 \(L\) 的指令。

代码:

#include<bits/stdc++.h>
#define ls x<<1
#define rs x<<1|1
using namespace std;
const int N=1e6+10;
char s[N];
int n;
struct node{
int l,r,mx,mi,f;
}e[N*4];
void up(int x){
e[x].mx=max(e[ls].mx,e[rs].mx);
e[x].mi=min(e[ls].mi,e[rs].mi);
}
void down(int x){
if(e[x].f==0)return;
int f=e[x].f;
e[ls].mx+=f,e[ls].f+=f;e[rs].mx+=f;e[rs].f+=f;
e[ls].mi+=f;e[rs].mi+=f;
e[x].f=0;
return;
}
void built(int x,int l,int r){
e[x].l=l,e[x].r=r;e[x].f=0;
if(l==r){
e[x].mx=e[x].mi=0;return;
}
int mid=(l+r)/2;
built(ls,l,mid);built(rs,mid+1,r);
up(x);
}
void add(int x,int LL,int RR,int val){
if(e[x].l>=LL&&e[x].r<=RR){
e[x].mx+=val;
e[x].mi+=val;
e[x].f+=val;
return;
}
down(x);
int mid=(e[x].l+e[x].r)/2;
if(LL<=mid)add(ls,LL,RR,val);
if(RR>mid)add(rs,LL,RR,val);
up(x);
}
int pd(int x,int pos){
if(e[x].l==e[x].r)return e[x].mx;
down(x);
int mid=(e[x].l+e[x].r)/2;
if(pos<=mid)return pd(ls,pos);
else return pd(rs,pos);
}
int query(int x,int LL,int RR){
if(e[x].l>=LL&&e[x].r<=RR){
return e[x].mx;
}
down(x);
int ans=0;
int mid=(e[x].l+e[x].r)/2;
if(LL<=mid)ans=max(ans,query(ls,LL,RR));
if(RR>mid)ans=max(ans,query(rs,LL,RR));
return ans;
}
int query1(int x,int LL,int RR){
if(e[x].l>=LL&&e[x].r<=RR){
return e[x].mi;
}
down(x);
int ans=1e6+10;
int mid=(e[x].l+e[x].r)/2;
if(LL<=mid)ans=min(ans,query1(ls,LL,RR));
if(RR>mid)ans=min(ans,query1(rs,LL,RR));
return ans;
}
int ans[N];
int vis[N];
int main()
{
//freopen("H:\\c++1\\in.txt","r",stdin);
//freopen("H:\\c++1\\out.txt","w",stdout);
scanf("%d",&n);
scanf("%s",s+1);
built(1,1,N-1);
int pos=1;
for(int i=1;i<=n;i++){
if(s[i]=='R')pos++,ans[i]=ans[i-1];
else if(s[i]=='L'){
ans[i]=ans[i-1];
if(pos==1)continue;
pos--;
}
else if(s[i]=='('){
int val=0;
if(vis[pos]==1)val=0;
else if(vis[pos]==-1)val=2;
else if(vis[pos]==0)val=1;
vis[pos]=1;
add(1,pos,N-1,val);
int flag=pd(1,N-1),flag1=query1(1,1,N-1);
if(flag==0&&flag1>=0){
ans[i]=query(1,1,N-1);
}else ans[i]=-1;
}else if(s[i]==')'){
int val=0;
if(vis[pos]==-1)val=0;
else if(vis[pos]==1)val=-2;
else if(vis[pos]==0)val=-1;
vis[pos]=-1;
add(1,pos,N-1,val);
int flag=pd(1,N-1),flag1=query1(1,1,N-1);
if(flag==0&&flag1>=0){
ans[i]=query(1,1,N-1);
}else ans[i]=-1;
//cout<<val<<" "<<flag<<" "<<pd(1,N-1)<<" "<<query(1,1,N-1)<<endl;
}else {
int val=0;
if(vis[pos]==0)val=0;
else if(vis[pos]==1)val=-1;
else if(vis[pos]==-1)val=1;
add(1,pos,N-1,val);
vis[pos]=0;
int flag=pd(1,N-1),flag1=query1(1,1,N-1);
if(flag==0&&flag1>=0){
ans[i]=query(1,1,N-1);
} else ans[i]=-1;
} }
for(int i=1;i<=n;i++)printf("%d%c",ans[i],i==n?'\n':' ');
return 0;
}

F. Economic Difficulties (DP)

题目链接

题目大意:

存在两颗树,两个树的根节点为 \(1\) ,一个从上到下,一个从下到上,叶子结点个数相同且为 \(n\) ,有 \(n\) 个电机,每一个电机分别连接上下各一个叶子结点,只要存在一个叶子结点那么该电机可以运行,问使得 \(n\) 个电机都可以运行,最多可以删除两棵树的边。

大致思路:

首先可以分析,对于每一个电机必然是删除上树或者下树的边,我们使用 \(val[i][j]\) 来表示仅不给 \([i,j]\) 电机供电最大能删除的边,分别求出两颗树的,用 \(dp[i]\) ,来表示使得 \([1,i]\) 的电机可以运行最多可以删除的边数,那么 \(dp[i]=max(dp[i],dp[j]+max(val1[j+1][i],val2[j+1][i])\) ;就是相当于对于 \([j+1][i]\) 区间我选择上面下面最大的进行删除。对于 \(val[i][j]\) 可以使用 \(dfs\) 一遍来求,但是可能会出现有的 \(val[i][j]\) 没有赋值,那是由于不能仅不给 \([i,j]\) 电机断点,换句话就是要是 \([i,j]\) 断电,会导致实际 \([x,y]\) 断电,且 \([x,y]\) 包括 \([i,j]\) ,理解还是比较简单的,比较好写。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=3e3+10;
vector<int>e[2][N];
int dp[N];
int l[2][N],r[2][N];
int val[2][N][N];
int tot[2][N];
int n;
void dfs(int _,int x){
if(x!=1)tot[_][x]=1;
for(int v:e[_][x]){
dfs(_,v);
l[_][x]=min(l[_][x],l[_][v]); // x结点子树最左边的点,和最右边的点
r[_][x]=max(r[_][x],r[_][v]);
tot[_][x]+=tot[_][v];
}
val[_][l[_][x]][r[_][x]]=max(val[_][l[_][x]][r[_][x]],tot[_][x]);
}
int main()
{
//freopen("H:\\c++1\\in.txt","r",stdin);
//freopen("H:\\c++1\\out.txt","w",stdout);
scanf("%d",&n);
for(int _=0;_<2;_++){ // 两颗树
int a;
scanf("%d",&a);
for(int i=1;i<=a;i++)l[_][i]=a+1,r[_][i]=0;
for(int i=1,x;i<a;i++){
scanf("%d",&x);
e[_][x].push_back(i+1);
}
for(int i=1,x;i<=n;i++){
scanf("%d",&x);l[_][x]=r[_][x]=i;
}
dfs(_,1);
}
for(int i=1;i<=n;i++)
for(int j=0;j<i;j++){
dp[i]=max(dp[i],dp[j]+max(val[0][j+1][i],val[1][j+1][i]));
}
printf("%d\n",dp[n]);
return 0;
}

Codeforces Round #603 (Div. 2) (题解)的更多相关文章

  1. Codeforces Round #182 (Div. 1)题解【ABCD】

    Codeforces Round #182 (Div. 1)题解 A题:Yaroslav and Sequence1 题意: 给你\(2*n+1\)个元素,你每次可以进行无数种操作,每次操作必须选择其 ...

  2. Codeforces Round #608 (Div. 2) 题解

    目录 Codeforces Round #608 (Div. 2) 题解 前言 A. Suits 题意 做法 程序 B. Blocks 题意 做法 程序 C. Shawarma Tent 题意 做法 ...

  3. Codeforces Round #525 (Div. 2)题解

    Codeforces Round #525 (Div. 2)题解 题解 CF1088A [Ehab and another construction problem] 依据题意枚举即可 # inclu ...

  4. Codeforces Round #528 (Div. 2)题解

    Codeforces Round #528 (Div. 2)题解 A. Right-Left Cipher 很明显这道题按题意逆序解码即可 Code: # include <bits/stdc+ ...

  5. Codeforces Round #466 (Div. 2) 题解940A 940B 940C 940D 940E 940F

    Codeforces Round #466 (Div. 2) 题解 A.Points on the line 题目大意: 给你一个数列,定义数列的权值为最大值减去最小值,问最少删除几个数,使得数列的权 ...

  6. Codeforces Round #603 (Div. 2) A. Sweet Problem(水.......没做出来)+C题

    Codeforces Round #603 (Div. 2) A. Sweet Problem A. Sweet Problem time limit per test 1 second memory ...

  7. Codeforces Round #677 (Div. 3) 题解

    Codeforces Round #677 (Div. 3) 题解 A. Boring Apartments 题目 题解 简单签到题,直接数,小于这个数的\(+10\). 代码 #include &l ...

  8. Codeforces Round #665 (Div. 2) 题解

    Codeforces Round #665 (Div. 2) 题解 写得有点晚了,估计都官方题解看完切掉了,没人看我的了qaq. 目录 Codeforces Round #665 (Div. 2) 题 ...

  9. Codeforces Round #160 (Div. 1) 题解【ABCD】

    Codeforces Round #160 (Div. 1) A - Maxim and Discounts 题意 给你n个折扣,m个物品,每个折扣都可以使用无限次,每次你使用第i个折扣的时候,你必须 ...

随机推荐

  1. re.sub 实现多处替换

    1   | 表示或的意思 将所有字母替换掉 result_content = re.sub('a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z', ...

  2. AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图

    AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图 链接 AtCoder 大意 在数轴上放上n个点,点i可能的位置有\(x_i\)或者\(y_i\ ...

  3. 花了两个星期,我终于把 WSGI 整明白了

    在 三百六十行,行行转 IT 的现状下,很多来自各行各业的同学,都选择 Python 这门胶水语言做为踏入互联网大门的第一块敲门砖,在这些人里,又有相当大比例的同学选择了 Web 开发这个方向(包括我 ...

  4. 区间DP复习

    区间DP复习 (难度排序:(A,B),(F,G,E,D,H,I,K),(C),(J,L)) 这是一个基本全在bzoj上的复习专题 没有什么可以说的,都是一些基本的dp思想 A [BZOJ1996] [ ...

  5. 5098: [BZOJ1098][POI2007]办公楼biu

    5098: [BZOJ1098][POI2007]办公楼biu 没有数据结构就很棒 一个看上去非常玄学的代码 const int N=1e5+10,M=2e6+10; int n,m; int fa[ ...

  6. PowerDesigner应用01 逆向工程之配置数据源并导出PDM文件

    物理数据模型(Physical Data Model)PDM,提供了系统初始设计所需要的基础元素,以及相关元素之间的关系:数据库的物理设计阶段必须在此基础上进行详细的后台设计,包括数据库的存储过程.操 ...

  7. prometheus(docker)安装和报警 -- nginx域名监控

    软件组件:prometheusalertmanagerprometheus-webhook-dingtalk nginx-vts-exporternginx (###--add-module=../n ...

  8. docker swarm和compose 的使用(阿里)

    基本的docker使用参考:Docker 入门 到部署Web 程序- (阿里面试常用的docker命令和优点) 昨天去阿里面试 问我如果给你5台服务器 如何部署docker,我说一个个拷贝,面试官听了 ...

  9. Windows 文件过滤驱动经验总结

    Windows 文件过滤驱动经验总结作者:sinister 本文转载自驱动开发网 看了 ChuKuangRen 的第二版<文件过滤驱动开发教程>后,颇有感触.我想,交流都是建立在平等的基础 ...

  10. mysql将多条结果拼接成一条结果

    1,实际数据 SELECT resource_id, resource_type FROM res_resource_mount 2,拼接之后数据 SELECT c.resource_id, GROU ...