每日两刷(2019/4/12)(Two Merged Sequences(贪心),Same Sum Blocks (Hard)(数据结构))

G. Two Merged Sequences

cf 难度2600(贪心)
链接:http://codeforces.com/problemset/problem/1144/G
Two integer sequences existed initially, one of them was strictly increasing, and another one — strictly decreasing.
Strictly increasing sequence is a sequence of integers [x1<x2<⋯<xk]. And strictly decreasing sequence is a sequence of integers [y1>y2>⋯>yl]. Note that the empty sequence and the sequence consisting of one element can be considered as increasing or decreasing.
Elements of increasing sequence were inserted between elements of the decreasing one (and, possibly, before its first element and after its last element) without changing the order. For example, sequences [1,3,4] and [10,4,2] can produce the following resulting sequences: [10,1,3,4,2,4], [1,3,4,10,4,2]. The following sequence cannot be the result of these insertions: [1,10,4,4,3,2] because the order of elements in the increasing sequence was changed.
Let the obtained sequence be a. This sequence a is given in the input. Your task is to find any two suitable initial sequences. One of them should be strictly increasing, and another one — strictly decreasing. Note that the empty sequence and the sequence consisting of one element can be considered as increasing or decreasing.
If there is a contradiction in the input and it is impossible to split the given sequence a into one increasing sequence and one decreasing sequence, print “NO”.

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

If there is a contradiction in the input and it is impossible to split the given sequence a into one increasing sequence and one decreasing sequence, print “NO” in the first line.
Otherwise print “YES” in the first line. In the second line, print a sequence of n integers res1,res2,…,resn, where resi should be either 0 or 1 for each i from 1 to n. The i-th element of this sequence should be 0 if the i-th element of a belongs to the increasing sequence, and 1 otherwise. Note that the empty sequence and the sequence consisting of one element can be considered as increasing or decreasing.

Examples
input

9
5 1 3 6 8 2 9 0 10

output

YES
1 0 0 0 0 1 0 1 0

input

5
1 2 4 0 2

output

NO

题目大意:

给你一串数字,让你把这串数字分成一串上升序列,一串下降序列。

题目思路:

贪心枚举,每次记录下上升up和下降down的值,然后比较:
if: up<a [ i ]<down
   if:a [ i ] < a [ i+1 ] up=a [ i ]
  else: down=a [ i ]
else if:a [ i ]<down down=a [ i ]
else if:a [ i ]>up up=a [ i ]
else NO

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX=200005;

int up,down,n,a[MAX];

int main(){
 scanf("%d",&n);
 int up=-1,down=0x3f3f3f3f;
 for(int i=0;i<n;i++){
    scanf("%d",&a[i]);
 }
  a[n]=MAX;
  for(int i=0;i<n;i++){
       if(a[i]<down&&a[i]>up){
        if(a[i]<a[i+1])
          up=a[i],a[i]=0;
        else
          down=a[i],a[i]=1;
       }
       else if(a[i]<down)
        down=a[i],a[i]=1;
       else if(a[i]>up)
        up=a[i],a[i]=0;
       else{
        printf("NO\n");
        return 0;
       }
  }
  printf("YES\n");
  for(int i=0;i<n;i++){
    printf("%d ",a[i]);
  }
  return 0;
}

F2. Same Sum Blocks (Hard)

cf 难度2200 链接 http://codeforces.com/problemset/problem/1141/F2
time limit per test 3 seconds
memory limit per test 256 megabytes
input standard input
output standard output
This problem is given in two editions, which differ exclusively in the constraints on the number n.
You are given an array of integers a[1],a[2],…,a[n]. A block is a sequence of contiguous (consecutive) elements a[l],a[l+1],…,a[r] (1≤l≤r≤n). Thus, a block is defined by a pair of indices (l,r).
Find a set of blocks (l1,r1),(l2,r2),…,(lk,rk) such that:
They do not intersect (i.e. they are disjoint). Formally, for each pair of blocks (li,ri) and (lj,rj) where i≠j either ri<lj or rj<li.
For each block the sum of its elements is the same. Formally,a[l1]+a[l1+1]+⋯+a[r1]=a[l2]+a[l2+1]+⋯+a[r2]=⋯=a[lk]+a[lk+1]+⋯+a[rk].
The number of the blocks in the set is maximum. Formally, there does not exist a set of blocks (l′1,r′1),(l′2,r′2),…,(l′k′,r′k′) satisfying the above two requirements with k′>k.
The picture corresponds to the first example. Blue boxes illustrate blocks.
Write a program to find such a set of blocks.

Input

The first line contains integer n (1≤n≤1500) — the length of the given array. The second line contains the sequence of elements a[1],a[2],…,a[n] (−105≤ai≤105).

Output

In the first line print the integer k (1≤k≤n). The following k lines should contain blocks, one per line. In each line print a pair of indices li,ri (1≤li≤ri≤n) — the bounds of the i-th block. You can print blocks in any order. If there are multiple answers, print any of them.

Examples
input

7
4 1 2 2 1 5 3

output

3
7 7
2 3
4 5

input

11
-5 -4 -3 -2 -1 0 1 2 3 4 5

output

2
3 4
1 1

input

1 1 1 1

output

4
4 4
1 1
2 2
3 3

题目大意:

给你一个长度为n的数组,找出尽量多的不相交的区间并且他们的区间和相等。

题目思路:

建立个map数组,存sum,和能构成sum的l和的数组。
向每个数的前面的数扫,每次都将能获得的sum存入map数组里
每次扫都比较一次map数组里的size大小,最后输出size最大的map数组即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX=200005;
int n,a[100005],sum,ans;
map<int,vector<pair<int,int>>>m;
int main(){
  cin>>n;
  for(int i=1;i<=n;i++){
    cin>>a[i];
    sum=0;
    for(int j=i;j>=1;j--){
        sum+=a[j];
        if(m[sum].size()==0||m[sum].back().second<j)
            m[sum].push_back(make_pair(j,i));
        if(i==1||m[sum].size()>m[ans].size()) ans=sum;
    }
  }
  cout<<m[ans].size()<<"\n";
  for(auto p:m[ans]) cout<<p.first<<" "<<p.second<<"\n";
  return 0;
}

今日小结:
建立一个map,用make_pair(int,int)…
可以建立一个map<int,vector<pair<int,int>>>的映射
向变长数组的map增加映射m[sum].push_back(make_pair(int ,int))

猜你喜欢

转载自blog.csdn.net/qq_43333395/article/details/89262878