CodeForces730E Award Ceremony (topological sorting + conclusion)


Title Link

Main idea of the title:

give n n List when n teams are closed a i a_i ai # and changes during listing d i d_i di​.

When the list is unveiled, the ranking of the team will change t i t_i ti​.

Note that when other teams unveil the list, their own team's ranking also changes dynamically.

The calculated change ranking is the ranking difference before and after their disclosure, rather than the difference between the final ranking and the initial ranking.

Then ask how to arrange the unveiling order so that s u m ( ∣ t i ∣ ) sum(|t_i|) sum(∣ ti ∣) maximum.

1 ≤ n ≤ 100 , 1 ≤ a i ≤ 100 , − 100 ≤ d i ≤ 100 1≤n≤100,1≤ai≤100, -100≤di≤100 1≤n≤100,1≤ai≤100,−100≤di≤100.


Consider the contribution of ranking changes between two teams.

  • If the relative ranking order of the two teams changes before and after the announcement, the answer is no matter how the announcement order of the two teams is arranged 1 1 1.

    i.e. assumptions i i i rank in j j j front( i < j i<j I < J), after unveiling j j j ranking higher i > j i>j i>j.

    There are two situations.

    • i i i the score decreases, j j j may rise or fall, but i i i must fall more sharply.
      • Let's say we open the list first i i i. Then i i i ranking becomes j j j later, the contribution is 1 1 1. Unveiling in the back j j j. Still in i i i before.
      • Let's say we open the list first j j j. Then j j j may have exceeded i i i. The list is still on the back i i i front; It may not be more than i i i. But i i i fell on the list after i was unveiled j j j behind.
    • i i i score increases, j j j must rise, and j j j must rise more fiercely. Assume that the process of unveiling is the same as above. No more details.
  • If the relative order of the two teams has not changed before and after the announcement. There are two cases.

    • No matter who debuts first, he keeps it i < j i<j i<j. Does not contribute to the answer.
    • i i i was j j After j exceeds, it exceeds again j j j. The answer is 2 2 2.

According to the above method, a directed acyclic graph will be obtained, and the revealed order can be obtained according to the topological sorting, but this problem is not required.

As long as the maximum result of the final change, directly enumerate the two teams to see which contribution belongs to the above situation. Just calculate.

The time complexity is O ( n 2 ) O(n^2) O(n2).

It is proved that the graph obtained by this method does not have rings.

Only the second point of the second case contributes 2 2 2. This case will need to consider the order of the two teams.

That is, only this case will add an edge to the graph, so the ring can only be generated in this place.

Suppose three teams i , j , k i,j,k i. J, K form a ring.

First of all, because there is an edge between the two teams, there is i i i can exceed j j j. Then he was j j j after the list is released, it will surpass. Only in this way can we make contributions 2 2 2.

( j , k ) , ( k , i ) (j,k),(k,i) The same is true for (j,k),(k,i).

Namely j j j more than k k k again k k k anti super, k k k more than i i i was again i i i anti super.

The order of these three announcements must be determined, so the change direction of ranking is fixed.

from ( i , j ) ( j , k ) (i,j)(j,k) The relationship between (i,j)(j,k) is known k k k more than i , j i,j i. J it's impossible to let i i i unveil the list again.

Therefore, this situation must be as shown in the figure:


#include <bits/stdc++.h>
using namespace std;
#define maxn 105
struct node { 
    int val, id, tag;
    bool operator < ( node &t ) {
        return val == t.val ? id < : val > t.val;
int n, ans;

int calc( int x, int y ) {
    node lst_x = a[x], lst_y = a[y];
    node new_x = lst_x, new_y = lst_y;
    new_x.val += lst_x.tag;
    new_y.val += lst_y.tag;
    if( lst_x < lst_y and new_y < new_x ) return 1;
    if( lst_y < lst_x and new_x < new_y ) return 1;
    if( lst_x < lst_y and new_x < new_y and new_y < lst_x ) return 2;
    if( lst_x < lst_y and new_x < new_y and lst_y < new_x ) return 2;
    if( lst_y < lst_x and new_y < new_x and new_x < lst_y ) return 2;
    if( lst_y < lst_x and new_y < new_x and lst_x < new_y ) return 2;
    return 0;

int main() {
    scanf( "%d", &n );
    for( int i = 1;i <= n;i ++ ) scanf( "%d %d", &a[i].val, &a[i].tag ), a[i].id = i;
    sort( a + 1, a + n + 1 );
    for( int i = 1;i <= n;i ++ )
        for( int j = i + 1;j <= n;j ++ )
            ans += calc( i, j );
    printf( "%d\n", ans );
    return 0;

Posted on Sun, 07 Nov 2021 23:38:10 -0500 by imranlink