Dual(构造)
题目描述
[Popskyy & tiasu - Dual](https://soundcloud.com/popskyy/popskyy-tiasu-dual)
The only difference between the two versions of this problem is the constraint on the maximum number of operations. You can make hacks only if all versions of the problem are solved.
You are given an array
In one operation, you choose
Make the array non-decreasing (i.e.,
输入格式
Each test contains multiple test cases. The first line contains the number of test cases
The first line contains a single integer
The second line contains
输出格式
For each test case, output your operations in the following format.
The first line should contain an integer
The next
After all the operations, the array
提示
In the first test case, by adding
In the second test case, the array changes as:
-
-
-
-
In the third test case, the final array is
输入输出样例
10 2 2 1 4 1 2 -10 3 5 2 1 1 1 1 8 0 0 0 0 0 0 0 0 5 1 2 -4 3 -10 10 11 12 13 14 15 -15 -16 -17 -18 -19 7 1 9 3 -4 -3 -2 -1 3 10 9 8 20 1 -14 2 -10 6 -5 10 -13 10 7 -14 19 -5 19 1 18 -16 -7 12 8 20 -15 -17 -13 8 14 -13 10 -4 11 -4 -16 -6 15 -4 -2 7 -9 5 -5 17
1 2 1 3 4 4 4 4 3 4 4 2 1 3 1 4 1 5 1 0 7 3 4 3 4 5 4 5 4 5 4 5 4 5 4 15 6 1 6 1 6 1 7 2 7 2 7 2 8 3 8 3 8 3 9 4 9 4 9 4 10 5 10 5 10 5 8 3 4 3 4 2 4 2 4 2 4 2 4 1 4 1 4 3 2 1 3 1 3 1 31 14 1 18 7 13 11 15 11 6 4 5 17 19 6 19 12 10 5 11 12 1 17 15 19 16 10 14 2 16 11 20 7 7 6 9 5 3 6 6 14 17 18 18 14 12 3 17 16 8 18 13 16 9 8 14 8 16 2 11 8 12 7 31 5 12 19 13 9 1 5 17 18 19 6 16 15 8 6 9 15 14 7 10 19 7 17 20 14 4 15 20 4 3 1 8 16 12 16 15 5 6 12 10 11 15 20 3 20 19 13 14 11 14 18 10 7 3 12 17 4 7 13 2 11 13
说明/提示
In the first test case, by adding 1=2a1=2 to 2a2 , we get the array [2,3][2,3] which is non-decreasing.
In the second test case, the array changes as:
- [1,2,−10,3][1,2,−10,3]
- [1,2,−10,6][1,2,−10,6]
- [1,2,−10,12][1,2,−10,12]
- [1,2,2,12][1,2,2,12]
In the third test case, the final array is [2,3,3,3,3][2,3,3,3,3] .
贪心地去想,我们一定尽可能让每次走的次数都具有价值。现在这样想,如果数组之内的正数多,那么我们让一个最大的数自增,增到什么程度呢?直到我们能把数组内的所有数变成正数为止。相反,如果负数多,那么我们把所有的数变为负数。显而易见,有一个规律:如果全部是正数,那么我们只需要用后一个数加上前一个数就可以了。
由于次数限制是
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<map> using namespace std; const int N=1e6+10,mod=1e9+7; // 定义常量 N 和 mod,用于数组大小和取模运算 string s; // 未使用,字符串变量 s int n,t,a[N],res,num,ans,m,k_z,k_f; // 定义各种整数变量和数组 int z,f,f_num,z_num,f_sum,z_sum; // 定义整数变量,用于记录正数和负数的数量及和 int maxx,minn,max_id,min_id; // 定义整数变量和索引,用于记录数组的最大和最小值的位置 int cnt1[N],cnt2[N]; // 计数数组,用于记录操作次数 map<int,pair<int,int>>mp1,mp2; // map 容器,用于记录操作的位置 bool vis[N]; // 布尔数组,未使用 // 处理正数情况的函数 void solve_z() { minn=abs(minn); // 通过操作,将最小负数变为正数的绝对值 while(a[max_id]<minn) res++,a[max_id]+=a[max_id],z_num++; res+=(n-1); // 将其他负数变为正数 for(int i=1;i<=n;i++) if(a[i]<0) res++,cnt1[i]++,mp1[i]={i,max_id},a[i]+=a[max_id]; cout<<res<<endl; // 输出操作次数和具体操作的位置 while(z_num!=0) z_num--,cout<<k_z<<" "<<k_z<<endl; for(int i=1;i<=n;i++) while(cnt1[i]!=0) cnt1[i]--,cout<<mp1[i].first<<" "<<mp1[i].second<<endl; for(int i=1;i<=n-1;i++) cout<<i+1<<" "<<i<<endl; } // 处理负数情况的函数 void solve_f() { while((-a[min_id])<maxx) a[min_id]+=a[min_id],res++,f_num++; res+=(n-1); // 将其他正数变为负数 for(int i=1;i<=n;i++) if(a[i]>0) res++,cnt1[i]++,mp1[i]={i,min_id},a[i]+=a[min_id]; cout<<res<<endl; // 输出操作次数和具体操作的位置 while(f_num!=0) f_num--,cout<<k_f<<" "<<k_f<<endl; for(int i=1;i<=n;i++) while(cnt1[i]!=0) cnt1[i]--,cout<<mp1[i].first<<" "<<mp1[i].second<<endl; for(int i=n;i>=2;i--) cout<<i-1<<" "<<i<<endl; } // 主处理函数 void solve() { cin>>n; // 输入数组长度 z=f=num=res=ans=m=z_num=f_num=z_sum=f_sum=0; mp1.clear(); // 清空 map 容器 memset(cnt2,0,sizeof cnt2); // 初始化计数数组 a[0]=-30,maxx=-30,minn=30; // 初始化数组和最大最小值 for(int i=1;i<=n;i++){ cin>>a[i]; // 输入数组元素 if(a[i]>0) z++,z_sum+=a[i]; // 统计正数个数和和 else if(a[i]==0) ; // 不处理为零的情况 else f++,f_sum+=a[i]; // 统计负数个数和和 if(maxx<a[i]) maxx=a[i],max_id=i,k_z=i; // 更新最大值和位置 if(minn>a[i]) minn=a[i],min_id=i,k_f=i; // 更新最小值和位置 } // 根据正数和负数的数量及和进行处理 if(z>f) if(z_sum<abs(f_sum)&&abs(z-f)<=5) solve_f(); else solve_z(); else{ if(z_sum>abs(f_sum)&&abs(z-f)<=5) solve_z(); else solve_f(); } } signed main() { std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>t; // 输入测试用例数量 while(t--){ solve(); // 处理每个测试用例 } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 因为Apifox不支持离线,我果断选择了Apipost!
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端