ZOJ 3981 Balloon Robot（提前位置取消等待时间）

Balloon Robot
Time Limit: 1 Second Memory Limit: 65536 KB
The 2017 China Collegiate Programming Contest Qinhuangdao Site is coming! There will be teams participating in the contest, and the contest will be held on a huge round table with seats numbered from 1 to in clockwise order around it. The -th team will be seated on the -th seat.

BaoBao, an enthusiast for competitive programming, has made predictions of the contest result before the contest. Each prediction is in the form of , which means the -th team solves a problem during the -th time unit.

As we know, when a team solves a problem, a balloon will be rewarded to that team. The participants will be unhappy if the balloons take almost centuries to come. If a team solves a problem during the -th time unit, and the balloon is sent to them during the -th time unit, then the unhappiness of the team will increase by . In order to give out balloons timely, the organizers of the contest have bought a balloon robot.

At the beginning of the contest (that is to say, at the beginning of the 1st time unit), the robot will be put on the -th seat and begin to move around the table. If the robot moves past a team which has won themselves some balloons after the robot’s last visit, it will give all the balloons they deserve to the team. During each unit of time, the following events will happen in order:

The robot moves to the next seat. That is to say, if the robot is currently on the -th () seat, it will move to the ()-th seat; If the robot is currently on the -th seat, it will move to the 1st seat.
The participants solve some problems according to BaoBao’s prediction.
The robot gives out balloons to the team seated on its current position if needed.
BaoBao is interested in minimizing the total unhappiness of all the teams. Your task is to select the starting position of the robot and calculate the minimum total unhappiness of all the teams according to BaoBao’s predictions.

Input

There are multiple test cases. The first line of the input contains an integer , indicating the number of test cases. For each test case:

The first line contains three integers , and (, , ), indicating the number of participating teams, the number of seats and the number of predictions.

The second line contains integers (, and for all ), indicating the seat number of each team.

The following lines each contains two integers and (, ), indicating that the -th team solves a problem at time according to BaoBao’s predictions.

It is guaranteed that neither the sum of nor the sum of over all test cases will exceed .

Output

For each test case output one integer, indicating the minimum total unhappiness of all the teams according to BaoBao’s predictions.

Sample Input

4
2 3 3
1 2
1 1
2 1
1 4
2 3 5
1 2
1 1
2 1
1 2
1 3
1 4
3 7 5
3 5 7
1 5
2 1
3 3
1 5
2 5
2 100 2
1 51
1 500
2 1000
Sample Output

1
4
5
50
Hint

For the first sample test case, if we choose the starting position to be the 1st seat, the total unhappiness will be (3-1) + (1-1) + (6-4) = 4. If we choose the 2nd seat, the total unhappiness will be (2-1) + (3-1) + (5-4) = 4. If we choose the 3rd seat, the total unhappiness will be (1-1) + (2-1) + (4-4) = 1. So the answer is 1.

For the second sample test case, if we choose the starting position to be the 1st seat, the total unhappiness will be (3-1) + (1-1) + (3-2) + (3-3) + (6-4) = 5. If we choose the 2nd seat, the total unhappiness will be (2-1) + (3-1) + (2-2) + (5-3) + (5-4) = 6. If we choose the 3rd seat, the total unhappiness will be (1-1) + (2-1) + (4-2) + (4-3) + (4-4) = 4. So the answer is 4.

题目大意

有一个长度为M(1M109)$M(1 \leqslant M \leqslant 10^9)$的环，一共有N(1N105)$N(1 \leqslant N \leqslant 10^5)$个队伍，他们有P(1P105)$P(1 \leqslant P \leqslant 10^5)$个提交。有一个机器人在初始在环上某一点，以1$1$单位每秒的速度顺时针运动，如果它走到某个队伍那里的时候他们有过了的还没发气球的题，就发个他们一个气球。每个气球的不满意度是过题到发气球的时间。要确定一个起时位置使得总不满意度最小，输出最小的总不满意度。

解题思路

首先对于这种按照特定方向运动有等待时间的情况，有一个常见套路，就是把他的位置提前，得到为了满足等待时间最开始所需要在的位置。这样就可以只考虑位置了。
很容易发现，每次过题的等待时间不会超过M$M$，所以我们就可以把转很多圈的情况等价成转一圈的情况。这样没次提交就只有两种情况，在第一圈得到气球，在第二圈得到气球，这个是由机器人的起始位置决定的。
又可以发现，如果起始位置的顺时针移动不经过预处理后的过题位置，那么总不满意度一定减少移动距离×P$\times P$。如果经过一个过题位置，就相当于第二圈给气球，则总不满意度一定再增加M$M$。于是我们可以知道起始位置一定在某个过题位置。把这些过题位置排序，先暴力扫一遍得到第一个位置起始的总不满意度，然后就可以O(1)$O(1)$向后递推每个起始位置的总不满意度。
总时间复杂度O(P)$O(P)$

AC代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
#define INF 0x3f3f3f3f3f3f3f3f
#define LL long long
#define mem(a,b) memset((a),(b),sizeof(a))

const int MAXN=100000+3;
LL N, M, P;
LL pos[MAXN], s[MAXN];//每个队的位置，预处理得到的过题位置

int main()
{
int T_T;
scanf("%d", &T_T);
while(T_T--)
{
scanf("%lld%lld%lld", &N, &M, &P);
for(int i=0;i<N;++i)
{
scanf("%lld", &pos[i]);
--pos[i];//为了方便后面取模，全部改为从0开始
}
for(int i=0;i<P;++i)
{
LL id, t;
scanf("%lld%lld", &id, &t);
s[i]=(pos[id-1]-t%M+M)%M;
}
sort(s, s+P);//把过题位置排序
LL cost=0;
for(int i=1;i<P;++i)//计算第一个位置的不满意度
cost+=s[i]-s[0];
LL ans=cost;
for(int i=1;i<P;++i)//计算各个位置作为初始位置的不满意度
{
cost=cost+M-P*(s[i]-s[i-1]);
ans=min(ans, cost);
}
printf("%lld\n", ans);
}

return 0;
}