题目 | 难度 | 知识点 |
---|---|---|
A 吔我大炮! | ★ | 签到 |
B 梦间 | ★ | 签到 |
C 坠入 | ★ | 签到 |
D 漫步 | ★★ | 思维 |
E 秘藏 | ★★ | 简单DP |
F 回响 | ★★★ | 构造,贪心 |
G 升!龙! | ★★ | dfs序 简单树形DP 树上前缀 |
F,G。F构造了半天没搞出来,G直接放弃了,其实就是用dfs序将其树上问题转区间问题,不过这玩意几年没碰了算是复习了一下倒是不难 。
吔我大炮!
cpp
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
int main(void)
{
LL a,b,c; cin>>a>>b>>c;
if(c>=a*b)puts("YES");
else puts("NO");
return 0;
}
梦间
cpp
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],b[N];
int main(void)
{
int t; cin>>t;
while(t--)
{
cin>>a[0]>>b[0]>>a[1]>>b[1]>>a[2]>>b[2];
int flag=0;
if(a[0]==0&&a[1]+a[2]==0) flag=1;
if(a[1]==0&&a[0]+a[2]==0) flag=1;
if(a[2]==0&&a[1]+a[0]==0) flag=1;
if(b[0]==0&&b[1]+b[2]==0) flag=1;
if(b[1]==0&&b[0]+b[2]==0) flag=1;
if(b[2]==0&&b[1]+b[0]==0) flag=1;
if(flag) puts("YES");
else puts("NO");
}
return 0;
}
坠入
cpp
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],b[N];
int main(void)
{
int t; cin>>t;
while(t--)
{
cin>>a[0]>>b[0]>>a[1]>>b[1]>>a[2]>>b[2];
int flag=0;
if(a[0]==(a[1]+a[2])/2.0) flag=1;
if(a[1]==(a[0]+a[2])/2.0) flag=1;
if(a[2]==(a[1]+a[0])/2.0) flag=1;
if(b[0]==(b[1]+b[2])/2.0) flag=1;
if(b[1]==(b[0]+b[2])/2.0) flag=1;
if(b[2]==(b[1]+b[0])/2.0) flag=1;
if(flag) puts("YES");
else puts("NO");
}
return 0;
}
漫步
cpp
#include<bits/stdc++.h>
using namespace std;
void solve(int x)
{
vector<int>ve;
while(x) ve.push_back(x%2),x/=2;
for(int i=0;i<ve.size();i++)
{
if(ve[i]==0){
cout<<(1<<i)<<'\n';
return;
}
}
cout<<-1<<'\n';
}
int main(void)
{
int t; cin>>t;
while(t--)
{
int x; cin>>x;
solve(x);
}
return 0;
}
秘藏

cpp
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],b[N],n,k,f[N][2];
int main(void)
{
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
memset(f,-1,sizeof f);
f[0][0]=0;
for(int i=1;i<=n;i++)
{
if(f[i-1][0]!=-1) f[i][0]=f[i-1][0]+a[i];
if(f[i-1][1]!=-1) f[i][1]=f[i-1][1]+b[i];
if(f[i-1][0]>=k) f[i][1]=max(f[i][1],f[i-1][0]-k+b[i]);
if(f[i-1][1]>=k) f[i][0]=max(f[i][0],f[i-1][1]-k+a[i]);
}
cout<<max(f[n][0],f[n][1])<<'\n';
return 0;
}
回响
处理两边边界,而后对于中间0填贪心的填,从大端点到小端点填,从大到小填而后再上下震荡。 例如5 0 0 0 3 就是 5 4 3 4 3
cpp
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],n;
int main(void)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int l=0;
while(l+1<=n&&a[l+1]==0) l++;
if(l==n){
for(int i=1;i<=n;i++) cout<<i<<" ";
return 0;
}
for(int i=l,j=a[l+1]+1;i>=1;i--,j++) a[i]=j;
int r=n+1;
while(r-1>=1&&a[r-1]==0) r--;
for(int i=r,j=a[r-1]+1;i<=n;i++,j++) a[i]=j;
for(int i=1;i<=n;i++)
{
if(a[i]==0)
{
int j=i;
while(j+1<=n&&a[j+1]==0) j++;
if(a[i-1]>=a[j+1]){
for(int z=i;z<=j;z++){
a[z]=a[z-1]-1;
if(a[z-1]==a[j+1]+1) a[z]=a[j+1];
else if(a[z-1]==a[j+1]) a[z]=a[j+1]+1;
}
}else{
for(int z=j;z>=i;z--){
a[z]=a[z+1]-1;
if(a[z+1]==a[i-1]+1) a[z]=a[i-1];
else if(a[z+1]==a[i-1]) a[z]=a[i-1]+1;
}
}
}
}
int flag=1;
for(int i=2;i<=n;i++) if(abs(a[i]-a[i-1])!=1) flag=0;
if(flag){
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
}else cout<<-1;
return 0;
}
升!龙!
就是一个前缀,后缀,中间的就是修改那段。这里是将树型能成dfs序搞成了区间。 dfs[i],就是i节点在区间中的位置。 rdfs[i],就是i节点的子节点在区间中的最大值。 redfs[i]就是区间i对应树上的节点是啥。 dp[i]是以dp[i]为根的最大子树和。 pre[i]是i到根节点的路径和。
cpp
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],n,m;
vector< vector<int> > e(N+1);
LL dfn[N],rdfn[N],redfn[N],dp[N],pre[N],idx;
LL lmax[N],rmax[N];
void dfs(int u,int fa)
{
dfn[u]=++idx;
redfn[dfn[u]]=u;
rdfn[u]=dfn[u];
pre[u]=pre[fa]+a[u];
dp[u]=a[u];
for(int i=0;i<e[u].size();i++)
{
int j=e[u][i];
if(j==fa) continue;
dfs(j,u);
dp[u]=max(dp[u],dp[j]+a[u]);
rdfn[u]=max(rdfn[u],rdfn[j]);
}
}
int main(void)
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=2;i<=n;i++)
{
int p; cin>>p;
e[i].push_back(p);
e[p].push_back(i);
}
dfs(1,0);
for(int i=1;i<=n;i++) lmax[i]=max(lmax[i-1],pre[redfn[i]]);
for(int i=n;i>=1;i--) rmax[i]=max(rmax[i+1],pre[redfn[i]]);
while(m--){
int x,y; cin>>x>>y;
LL ans=max(lmax[dfn[x]-1],rmax[rdfn[x]+1]);
ans=max(ans,pre[y]+dp[x]);
cout<<ans<<'\n';
}
return 0;
}