题意:dddd
思路:由于操作次数可以任取一个成立的,那么我们就可以把所有数字改成相等的,然后排序后与原数组对比
diamond:
#include<bits/stdc++.h>
#define deb(x) cout << #x << " = " << x << '\n';
#define INF 0x3f3f3f3f
using namespace std;
void solve()
{
int n;
cin >> n;
vector<int>a(n);
for(int i = 0; i < n; i ++)
cin >> a[i];
int ans = 0;
for(int i = n - 1; i >= 1; i --)
{
if(a[i] >= a[i - 1])
{
continue;
}
ans = max(ans, a[i]);
ans = max(ans, a[i - 1]);
}
vector<int>b = a;
sort(b.begin(), b.end());
if(a == b)
{
cout << 0 << endl;
return;
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
//t = 1;
cin >> t;
while(t--)
solve();
}
题意:dddd
思路:当n为1,no,然后看1的个数与ai-1的sum相比,如果sum>=cnt,则YES,否则NO
diamond:
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
void solve()
{
int n;
cin >> n;
vector<int>a(n);
int sum = 0;
int cnt = 0;
for(int i = 0; i < n; i ++)
{
cin >> a[i];
sum += (a[i] - 1);
if(a[i] == 1)
cnt ++;
}
if(n == 1)
{
cout << "NO" << endl;
return;
}
if(sum >= cnt)
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
// int need;
// if(n % 2)
// need = (n) / 2 + (n / 2) * 2 + 3;
// else
// need = n / 2 + n;
// if(sum >= need)
// cout << "YES" << endl;
// else
// cout << "NO" << endl;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
//t = 1;
cin >> t;
while(t--)
solve();
}
题意:给定两个整数n和k,一个序列a,你可以进行不超过K次如下操作
-
选择一个i,ai<=ai+1
-
使ai++
问求操作完成后,最大的ai是多少
思路:我们可以对答案进行二分,假设我们的答案是8,原数组a是 6 4 6,我们可以发现,6要变成8,4要变成7,6要变成6,8 7 6 最小的操作次数是5,其实要是最小,就要把序列变成递减为1的序列,然后我们二分答案,枚举每一个位置为起点,然后把他变成递减序列,假设某点是大于该点的目标值的,那么我们就break,记录操作次数,与k比较,有一个成立,就记录答案,更新l区间,反之更新r区间
diamond:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+10;
#define PII pair<int,int>
void solve() {
int n,k;
cin>>n>>k;
vector<int>q;
for (int i = 0; i <n ; ++i) {
int x;
cin>>x;
q.push_back(x);
}
auto check=[&](int mid){
for (int i = 0; i <n ; ++i) {
int cs=0,mudi=mid;
for (int j = i; j <n ; ++j) {
if(q[j]<mudi){
if(j==n-1)cs=1e15;
cs+=mudi-q[j];
mudi--;
}
else{
break;
}
}
if(k>=cs){
return true;
}
}
return false;
};
int ans=q[n-1];
int l=1,r=1e11;
while (l<=r){
int mid=l+r>>1;
if(check(mid)){
l=mid+1;
ans=max(ans,mid);
}
else{
r=mid-1;
}
}
cout<<ans<<endl;
}
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
}
题意:交互题,有一个1到n的排列p,每次询问你花费(r-l)^2的代价询问[l,r]逆序对的个数,你需要在5 * n^2的代价内找到最大值n的位置。
思路:我们可以这样考虑,假设相邻两个数a,b,问a,b的逆序对个数,如果是1,则a更大,若是0,则b更大,因此我们可以对区间进行线段树形式的划分,递归求解每一个区间的最大值在哪个位置,然后往上推,这样操作把区间划分为4 n个,代价最大小于5 n^2。注意交互题的形式,需要刷新窗口,endl自带刷新
diamond:
#include<bits/stdc++.h>
using namespace std;
//#define int long long
int query(int l,int r){
if(l==r)return 0;
else {
cout<<"? "<<l<<' '<<r<<endl;
int z;
cin>>z;
return z;
}
}
int dfs(int l,int r){
if(l==r)return r;
else {
int mid = (l + r) / 2;
int lz = dfs(l, mid), rz = dfs(mid + 1, r);
int z1 = query(lz, rz - 1);
int z2 = query(lz, rz);
if (z1 == z2) {
return rz;
}
else {
return lz;
}
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin>>t;
while(t--){
int n;
cin>>n;
int w=dfs(1,n);
cout<<'!'<<' '<<w<<endl;
}
return 0;
}