并查集
cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+5;
const int INF=0x3f3f3f3f3f3f3f3f;
int n,m;
int a[N],tree[N];
int get(int z){
if(tree[z]!=z) tree[z]=get(tree[z]);
return tree[z];
}
int nxt(int pos){
if(pos==n) return 1;
return pos+1;
}
void solve(){
cin>>n>>m;
int ans=0;
for(int i=1;i<=n;i++){
cin>>a[i];
tree[i]=i;
}
int cnt=1;
while(m--){
int tp;
cin>>tp;
cnt+=tp;
while(cnt>n)cnt=cnt-n;
cnt=get(cnt);
ans+=a[cnt];
tree[cnt]=get(nxt(cnt));
}
cout<<ans<<' '<<cnt;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t=1;
while(t--){
solve();
}
return 0;
}
set
cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+5;
const int INF=0x3f3f3f3f3f3f3f3f;
int n,m;
int a[N];
void solve(){
cin>>n>>m;
int ans=0;set<int>s;
for(int i=1;i<=n;i++){
cin>>a[i];
s.insert(i);
}
int cnt=1;
while(m--){
int tp;
cin>>tp;
cnt+=tp;
while(cnt>n)cnt-=n;
auto it=s.lower_bound(cnt);
if(it==s.end())it=s.begin();
cnt=*it;
ans+=a[cnt];
s.erase(cnt);
}
cout<<ans<<' '<<cnt;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t=1;
while(t--){
solve();
}
return 0;
}
二维状压DP
贪心可行性判断
cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=200005;
const int INF=0x3f3f3f3f3f3f3f3f;
int n,m,k;
int a[N],b[N],c[N],d[N];
int suma[N],sumb[N],pa[N],pb[N];
void solve(){
int ans=-INF;
cin>>n>>m>>k;
c[0]=0;suma[0]=0;pa[0]=0;
for(int i=1;i<=n;i++){
cin>>a[i]>>c[i],suma[i]=suma[i-1]+a[i];
pa[i]=pa[i-1]+c[i-1];
}
d[0]=0;sumb[0]=0;pb[0]=0;
for(int i=1;i<=m;i++){
cin>>b[i]>>d[i],sumb[i]=sumb[i-1]+b[i];
pb[i]=pb[i-1]+d[i-1];
}
int lo=max(0LL,k-m),hi=min(k,n);
for(int i=lo;i<=hi;i++){
if(pa[i]<=k-i&&i>=pb[k-i])ans=max(ans,suma[i]+sumb[k-i]);
}
if(ans==-INF)cout<<"IMPOSSIBLE"<<endl;
else cout<<ans<<endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;cin>>t;
while(t--) solve();
return 0;
}