codeforces1144D Equalize Them All 贪心

You are given an array a consisting of n integers. You can perform the following operations arbitrary number of times (possibly, zero):

  1. Choose a pair of indices (i,j)such that |i−j|=1 (indices i and j are adjacent) and set ai:=ai+|ai−aj|;
  2. Choose a pair of indices (i,j)such that |i−j|=1 (indices i and j are adjacent) and set ai:=ai−|ai−aj|.

The value |x|means the absolute value of x. For example, |4|=4, |−3|=3.
Your task is to find the minimum number of operations required to obtain the array of equal elements and print the order of operations to do it.
It is guaranteed that you always can obtain the array of equal elements using such operations.
Note that after each operation each element of the current array should not exceed 1018 by absolute value.

Input
The first line of the input contains one integer n
(1≤n≤2⋅105) — the number of elements in a.
The second line of the input contains n integers a1,a2,…,an (0≤ai≤2⋅105), where ai is the i-th element of a

.
Output

In the first line print one integer k — the minimum number of operations required to obtain the array of equal elements.
In the next k lines print operations itself. The p-th operation should be printed as a triple of integers (tp,ip,jp), where tp is either 1 or 2 (1 means that you perform the operation of the first type, and 2 means that you perform the operation of the second type), and ip and jp are indices of adjacent elements of the array such that 1≤ip,jp≤n, |ip−jp|=1. See the examples for better understanding.
Note that after each operation each element of the current array should not exceed 1018by absolute value.
If there are many possible answers, you can print any.

Examples
Input

5
2 4 6 6 6

Output

2
1 2 3 
1 1 2 

Input

3
2 8 10

Output

2
2 2 1 
2 3 2 

Input

4
1 1 1 1

Output

0

新学的真超链接真好玩


给出一个序列,你可以进行两个操作,现在要求最少次数的操作方案,使得这个序列相等。
分析一下这两个式子,不难得出,无论ai>aj或是ai<aj,都可以使ai=aj
因为最终状态是所有字符都相等,故操作的次数就是 字符串的长度- 全部相等时的字符在原串出现的次数,所以确定出现最多的为相等值,重点在模拟。


#include <stdio.h>
#include <climits>
#include <cstring>
#include <time.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <utility>
#include <vector>
#include <string>

#define maxn 200005
#define INF 0x3f3f3f3f
#define ll long long
#define Pair pair<int,int>
#define re return

#define getLen(name,index) name[index].size()
#define mem(a,b) memset(a,b,sizeof(a))
#define Make(a,b) make_pair(a,b)
#define Push(num) push_back(num)
#define rep(index,star,finish) for(register int index=star;index<finish;index++)
#define drep(index,finish,star) for(register int index=finish;index>=star;index--)
using namespace std;
struct Opera{
    int index;
    int i,j;
};

int store[maxn];
Opera opera[maxn*2];
map<int,int> mapping;
inline ll cal(int index,int i,int j);
int main(){
    int N;
    scanf("%d",&N);
    int sup=INT_MIN,equ;
    rep(i,1,N+1){
        scanf("%d",&store[i]);
        mapping[store[i]]++;
        if(mapping[store[i]]>sup){
            sup=mapping[store[i]];
            equ=store[i];
        }
    }

    int t=0,pos=1;
    while(pos<=N){
        while(pos<=N && store[pos]!=equ){
            pos++;
        }
        if(pos==N+1)
            break;
        drep(i,pos-1,1){
            if(store[i]==equ)
                break;
            if(equ<store[i]){
                opera[t].index=2;
            }else{
                opera[t].index=1;
            }
            opera[t].i=i,opera[t].j=i+1;
            t++;
        }
        pos++;
    }
    pos--;
    while(store[pos]!=equ)
        pos--;
    rep(i,pos+1,N+1){
        if(equ<store[i]){
            opera[t].index=2;
        }else
            opera[t].index=1;
        opera[t].i=i,opera[t].j=i-1;
        t++;
    }


    printf("%d\n",t);
    rep(i,0,t){
        store[opera[i].i]=cal(opera[i].index,opera[i].i,opera[i].j);
        printf("%d %d %d\n",opera[i].index,opera[i].i,opera[i].j);
    }

    re 0;
}
inline ll cal(int index,int i,int j){
    switch(index){
        case 1:
            re store[i]+abs(store[i]-store[j]);
        case 2:
            re store[i]-abs(store[i]-store[j]);
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CodeForces - 616D是一个关于找到一个序列中最长的第k好子段的起始位置和结束位置的问题。给定一个长度为n的序列和一个整数k,需要找到一个子段,该子段中不超过k个不同的数字。题目要求输出这个序列最长的第k好子段的起始位置和终止位置。 解决这个问题的方法有两种。第一种方法是使用尺取算法,通过维护一个滑动窗口来记录\[l,r\]中不同数的个数。每次如果这个数小于k,就将r向右移动一位;如果已经大于k,则将l向右移动一位,直到个数不大于k。每次更新完r之后,判断r-l+1是否比已有答案更优来更新答案。这种方法的时间复杂度为O(n)。 第二种方法是使用枚举r和双指针的方法。通过维护一个最小的l,满足\[l,r\]最多只有k种数。使用一个map来判断数的种类。遍历序列,如果当前数字在map中不存在,则将种类数sum加一;如果sum大于k,则将l向右移动一位,直到sum不大于k。每次更新完r之后,判断i-l+1是否大于等于y-x+1来更新答案。这种方法的时间复杂度为O(n)。 以上是两种解决CodeForces - 616D问题的方法。具体的代码实现可以参考引用\[1\]和引用\[2\]中的代码。 #### 引用[.reference_title] - *1* [CodeForces 616 D. Longest k-Good Segment(尺取)](https://blog.csdn.net/V5ZSQ/article/details/50750827)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Codeforces616 D. Longest k-Good Segment(双指针+map)](https://blog.csdn.net/weixin_44178736/article/details/114328999)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值