Sicily 8843. Ranking and Friendship

8843. Ranking and Friendship

Constraints

Time Limit: 1 secs, Memory Limit: 256 MB

Description

Since teacher Herkabe has started ranking his N students, the number of friendships in his class has sharply fallen. The students near the bottom of the rankings list have become jealous of the top students, while the top students started looking down on their less successful colleagues.
According to Malcolm's observations, the following rule holds: two students are friends if their ranks are close enough, more precisely, if they differ by at most K. For example, if K = 1, then only neighbouring students on the rankings list are friends. Furthermore, two students are good friends if they are friends and their names have the same length.
Write a program to calculate the number of pairs of good friends in this gifted class.

Input

The first line of input contains two positive integers, N (3 ≤ N ≤ 300 000) and K (1 ≤ K ≤ N), from the problem statement.
Each of the following N lines contains a single student's name. The names are given in the order they appear on the rankings list. They consist of between 2 and 20 (inclusive) uppercase English letters.

Output

The first and only line of output must contain the required number of pairs.

Sample Input

样例1:
4 2
IVA
IVO
ANA
TOM
样例2:
6 3
CYNTHIA
LLOYD
STEVIE
KEVIN
MALCOLM
DABNEY

Sample Output

样例1:
5
样例2:
2

Problem Source

2013年每周一赛第七场/COCI 2012.12

// Problem#: 8843
// Submission#: 3557694
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <stdio.h>
#include <algorithm>
using namespace std;

struct man {
    int rank, length;
};

man M[300005];

bool cmp(const man & m1, const man & m2) {
    if (m1.length == m2.length) return m1.rank < m2.rank;
    return m1.length < m2.length;
}

inline int ABS(int a) {if (a < 0) return -a; return a;}

int main() {
    int N, K;
    scanf("%d%d\n", &N, &K);
    char name[25];
    int l = 0;
    for (int i = 0; i < N; i++) {
        M[i].rank = i;
        gets(name);
        l = 0;
        while (name[l]) l++;
        M[i].length = l;
    }
    sort(M, M + N, cmp);
    int startPos = 0, endPos = 0;
    long long ans = 0;
    for (int i = 1; i < N; i++) {
        if (M[startPos].length == M[i].length)
            if (ABS(M[startPos].rank - M[i].rank) <= K) {
                ans += endPos - startPos + 1;
                endPos++;
            } else {
                while (startPos <= endPos && ABS(M[startPos].rank - M[i].rank) > K) startPos++;
                ans += endPos - startPos + 1;
                endPos++;
            }
        else startPos = endPos = i;    
    }
    printf("%lld\n", ans);

    return 0;
}                                 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值