A.最大值只能由自己除,所以无解的情况只能是全部相同,否则直接最大值放c即可
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10,mod=998244353;
#define int long long
typedef long long LL;
typedef pair<int, int> PII;int n,m,k;
int a[N],b[N];void solve(){set<int> st;cin>>n;for(int i=1;i<=n;i++){cin>>a[i];st.insert(a[i]);}if(st.size()==1) cout<<"-1\n";else{vector<int> c,d;auto mx=*st.rbegin();for(int i=1;i<=n;i++)if(a[i]==mx) c.push_back(a[i]);else d.push_back(a[i]);cout<<d.size()<<" "<<c.size()<<"\n";for(auto x:d) cout<<x<<" ";cout<<'\n';for(auto x:c) cout<<x<<" ";cout<<'\n';}}
signed main(){cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);int t=1;cin>>t;while(t--) solve();return 0;
}
B.b直接枚举其他数组的最小值放到当前数组(其他数组的最小值集中放在一个数组肯定最优的)
所以记录一下最小值和次小值即可
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5+10;
#define int long long
int n,m;
vector<int> a[N];
int mn1[N],mn2[N];
void solve(){cin>>n;int res=0;for(int i=1;i<=n;i++){cin>>m;a[i].clear();for(int j=1;j<=m;j++){int x;cin>>x;a[i].push_back(x);}sort(a[i].begin(),a[i].end());mn1[i]=a[i][0];mn2[i]=a[i][1];res+=mn1[i];}int mx=res;vector<int> mn(n+10,0x3f3f3f3f);for(int i=n;i>=1;i--) mn[i]=min(mn[i+1],mn1[i]);vector<int> s1(n+10,0);vector<int> s2(n+10,0);for(int i=1;i<=n;i++) s1[i]=s1[i-1]+mn1[i],s2[i]=s2[i-1]+mn2[i];vector<int> l(n+10,0x3f3f3f3f);vector<int> r(n+10,0x3f3f3f3f);for(int i=1;i<=n;i++) l[i]=min(l[i-1],mn1[i]);for(int i=n;i>=1;i--) r[i]=min(r[i+1],mn1[i]);for(int i=1;i<=n;i++){int now=s2[n]-mn2[i]+min({mn1[i],l[i-1],r[i+1]});mx=max(mx,now);}cout<<mx<<"\n";
}signed main(){cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);int t=1;cin>>t;while(t--) solve();
}
C.
额直接打表看的规律,直接调用next_permuatation 打表前10个答案的数组,观察一下可得
前半部分按顺序,后半部分翻转即可
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5+10;
#define int long long
int n,m;
//int a[N];
int b[N];
void solve(){cin>>n;if(n==2){cout<<2<<"\n";return ;}int res=0;vector<int> s(n+10,0);vector<int> mx(n+10,0);for(int i=1;i<=n;i++){b[i]=i;s[i]=s[i-1]+b[i]*i;mx[i]=max(mx[i-1],b[i]*i);}for(int i=1;i<=n;i++){int now=s[i];int nw=n;int mxx=0;for(int j=i+1;j<=n;j++){now+=nw*j;mxx=max(mxx,nw*j);nw--;}mxx=max(mxx,mx[i]);res=max(res,now-mxx);}cout<<res<<"\n";}signed main(){cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);int t=1;cin>>t;while(t--) solve();
}
D:
如果当前点在[l,r]中,那么他可以通过跳跃到有交集的且比当前区间靠右的那个区间的b那里
比如起点在第一个区间,无论在哪个点都能跳到b1,如果在b1那么和他相交的下一个区间她也能跳到b2,因为相交l<=b1
如果在当前点>b1 那么她依然能跳到b1,且更大可能能跳到下一个区间,且它依然能利用b1这个点跳跃到下一个区间
所以其实能跳跃的区间范围是[l,b],直接合并有交集的跳跃区间即可
所以可以直接预处理出当前点能往右跳到哪里,最后二分出当前询问的点在哪个区间,
我用的并查集合并的
还有个问题就是二分的时候按照左端点排序,二分出最靠右的区间r>=l
因为第一个红线和第二个红线其实已经合并了,但是都没r优,所以要二分出最靠右的区间r>=l
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10,mod=998244353;
#define int long long
typedef long long LL;
typedef pair<int, int> PII;int n,m,k;
PII a[N];
class dsu {public:vector<int> p;vector<int> mx;int n;dsu(int _n) : n(_n) {p.resize(n);iota(p.begin(), p.end(), 0);mx.resize(n);}inline int get(int x) {return (x == p[x] ? x : (p[x] = get(p[x])));}inline bool unite(int x, int y) {x = get(x);y = get(y);if (x != y) {mx[y]=max(mx[x],mx[y]);p[x] = y;return true;}return false;}
};void solve(){cin>>n;dsu d(n+10);for(int i=1;i<=n;i++){int l,r,bb,aa;cin>>l>>r>>aa>>bb;a[i]={l,bb};}sort(a+1,a+1+n,[&](const auto&p,const auto&q){return p.first<q.first; });for(int i=1;i<=n;i++) d.mx[i]=a[i].second;for(int i=2;i<=n;i++){int l=a[i].first,r=a[i].second;int x=d.get(i-1),y=d.get(i);if(l<=d.mx[x]){d.unite(x,y);}}int q;cin>>q;while(q--){int x;cin>>x;int res=x;int l=1,r=n;while(l<r){int mid=l+r+1>>1;if(a[mid].first<=x) l=mid;else r=mid-1;}if(a[l].first<=x&&d.mx[d.get(l)]>=x){res=max(res,d.mx[d.get(l)]);}if(q)cout<<res<<" ";else cout<<res<<"\n";}
}
signed main(){cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);int t=1;cin>>t;while(t--) solve();return 0;
}
E:
设f为前i个点,且当前线段长度总和为k的贡献最大值
复杂度是n*k*k,因为要枚举当前长度和上一个线段总和的长度
考虑优化把绝对值拆开
首先ai和bi已经枚举了,且下标一样,所以已经固定了,接下来就是维护另一个aj和bj
copy一下别人的,别人写的清晰
#include<bits/stdc++.h>
using namespace std;
const int N = 3010,mod=998244353;
#define int long long
typedef long long LL;
typedef pair<int, int> PII;int n,m,k;
int a[N],b[N];
int mx[2][2][N];
void solve(){cin>>n>>k;for(int i=1;i<=n;i++) cin>>a[i];for(int i=1;i<=n;i++) cin>>b[i];memset(mx,-0x3f,sizeof(mx));vector<vector<int>> f(n+10,vector<int>(k+10,0));for(int i=1;i<=n;i++){for(int j=1;j<=min(i,k);j++){for(int x=0;x<2;x++){for(int y=0;y<2;y++){mx[x][y][i - j] = max(mx[x][y][i - j], f[i - 1][j - 1] + (x == 0 ? a[i] : -a[i]) + (y == 0 ? b[i] : -b[i]));}}for(int x=0;x<2;x++){for(int y=0;y<2;y++){f[i][j]=max(f[i][j],f[i-1][j]);f[i][j]=max(f[i][j],mx[x][y][i-j]+ (x == 0 ? -b[i] : b[i]) + (y == 0 ? -a[i] : a[i]));}}}}cout<<f[n][k]<<"\n";}
signed main(){cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);int t=1;cin>>t;while(t--) solve();return 0;
}