| 题目 | 难度 | 知识点 |
|---|---|---|
| A Onewan的疑惑 | ★ | 签到 |
| B 菲菲姐的游戏 | ★ | 思维 |
| C 猪猪养成计划1 | ★ | set/模拟/并查集 |
| D 猪猪养成计划2 | ★★ | 线性DP |
最无语的一场,A题再瞎搞心态崩了。
Onewan的疑惑
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
int main(void)
{
LL n; cin>>n;
LL l=max(n-5201314-14174017,1ll);
LL r=n;
cout<<r-l+1;
return 0;
}
菲菲姐的游戏
每个人的最优都是只选一个,且选最大的数。 故前后缀,枚举即可。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*2+10;
typedef long long int LL;
LL a[N],n,k1,k2;
LL l[N],r[N];
int main(void)
{
cin>>n>>k1>>k2;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) l[i]=max(l[i-1],a[i]);
for(int i=n;i>=1;i--) r[i]=max(r[i+1],a[i]);
int flag=0;
for(int i=1;i<=n-1;i++)
{
if(l[i]>r[i+1]) flag=1;
}
if(flag) puts("Yes");
else puts("No");
return 0;
}
猪猪养成计划1
模拟,因为未标记的数量会越来越少。
#include<bits/stdc++.h>
using namespace std;
deque<int>q,temp;
map<int,int>mp;
int n,m,cnt;
int main(void)
{
cin>>n>>m;
for(int i=1;i<=n;i++) q.push_back(i);
while(m--)
{
int op; cin>>op;
if(op==1)
{
int l,r; cin>>l>>r;
temp.clear();
while(q.size())
{
while(q.front()<l) temp.push_back(q.front()),q.pop_front();
if(q.size()&&q.front()>=l&&q.front()<=r) mp[q.front()]=++cnt,q.pop_front();
if(q.size()&&q.front()>r) break;
}
while(q.size()) temp.push_back(q.front()),q.pop_front();
q=temp;
}else
{
int x; cin>>x;
cout<<mp[x]<<'\n';
}
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int p[N],ans[N],n,q,cnt;//p[i]是以i为左端点,最右端点的下一个
int find(int x)
{
if(x!=p[x]) p[x]=find(p[x]);
return p[x];
}
void merge(int a,int b)
{
int fa=find(a),fb(find(b));
if(fa>fb) swap(fa,fb);
p[fa]=fb;
}
int main(void)
{
cin>>n>>q;
for(int i=1;i<=n+1;i++) p[i]=i;
//n+1是一个哨兵,避免死循环
while(q--)
{
int op; cin>>op;
if(op==1)
{
int l,r; cin>>l>>r;
for(int i=l;i<=r;i=find(i))
{
if(ans[i]==0) ans[i]=++cnt;
merge(i,i+1);
}
}else
{
int x; cin>>x;
cout<<ans[x]<<'\n';
}
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,q,ans[N],cnt;
set<int>st;
int main(void)
{
cin>>n>>q;
for(int i=1;i<=n;i++) st.insert(i);
while(q--)
{
int op; cin>>op;
if(op==1)
{
int l,r; cin>>l>>r;
auto it=st.lower_bound(l);
while(it!=st.end() && *it<=r )
{
ans[*it]=++cnt;
it=st.erase(it);
}
}else{
int x; cin>>x;
cout<<ans[x]<<'\n';
}
}
return 0;
}
猪猪养成计划2
dp[i]表示前i天都陪伴好的最小的变化值。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long int LL;
LL a[N],b[N],val[N];
LL n,m,dp[N],sum;
int main(void)
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
{
cin>>b[i]>>val[i];
sum+=val[i];
}
vector< vector<pair<int,int>> > ve(n+2);
for(int i=1;i<=n;i++) ve[a[i]].push_back({b[i],val[i]});
memset(dp,0x3f,sizeof dp);
dp[0]=0;
for(int i=0;i<=n;i++)
{
for(int j=0;j<ve[i].size();j++)
{
dp[i+m]=min(dp[i+m],dp[i]+ve[i][j].first-ve[i][j].second);//陪伴
}
dp[i+1]=min(dp[i],dp[i+1]);//第i天这个猪不陪伴
}
cout<<sum+dp[n];
return 0;
}