1. 程式人生 > >SYZOJ 480【WQH大佬的逃♂離】 的題解

SYZOJ 480【WQH大佬的逃♂離】 的題解

這道題是我在英語課的時候感覺無聊,而又看到WQH大佬,於是突發靈感,想出了這道水題。

題目描述

眾所周知,WQH大佬非常NB,所以經常有很多人來找WQH大佬問問題或者Van♂遊戲。

但是WQH不能在別人身上花太多時間,因為他還有一個【資料刪除】,WQH每天需要抽一些時間陪【資料刪除】van♂遊戲。

WQH每天有t個單位時間,而每天都有n個人來找WQH大佬,第i個人會在l[i],r[i]的單位時間段內圍在WQH大佬身邊,假如在某個時間段WQH大佬身邊沒有人,他就可以陪【資料刪除】van♂遊戲。但是因為來找WQH大佬的人實在是太多了,所以WQH決定找一個“性♂運”學生,讓這個“性♂運”學生改天再來,從而讓自己有更多的時間來陪【資料刪除】van♂遊戲。

但是WQH大佬和【資料刪除】van♂的太多了,所以WQH大佬感到一絲虛♂弱,所以就來找你幫忙,將哪一個學生作為“性♂運”學生可以讓WQH大佬陪【資料刪除】的時間最多。如果無解,則輸出 ”and*kgou“。 無解情況指無論讓哪個學生作為性♂運學生,都不能使WQH大佬陪【資料刪除】van♂的時間更多.

WQH大佬:“你有毒吧?”。

本蒟蒻第一次出題,真·原創題,可能比較水,資料也是隨機數。如果有錯誤,歡迎指正! 感謝@door♂陽提供的5組毒瘤資料(你們T掉的點都是他出的!)和樣例解釋!

輸入格式

第一行一個整數T,表示有T組資料

接下來的T組測試資料:

第一行有2個整數n,t,用空格隔開,分別表示有多少個人來找

WQH大佬,而WQH大佬有t各單位時間。

接下來n行,每行2個整數l,r,用空格隔開,分別表示第i個人在l,r單位時間段會在WQH大佬身邊。

友情提示:最好~~(必須)~~加一個快讀

輸出格式 T行。

兩個整數分別代表 “性♂運”學生的編號 和 把那個學生作為“性♂運”學生可以獲得陪【資料刪除】van♂遊戲的時間。

如果無解,則輸出 ”and*kgou“

(因為Andy真的可gou)

樣例:

input

1
3 8
1 8
2 4
5 7

output

1 3

樣例解釋

圖中紅色曲線部分為選中的人,直線上紅色區域為空閒時間。

input

4
10 23
4 15
16 19
15 18
18 18
7 11
20 22
20 21
23 23
14 21
7 8

5 35
32 32
5 25
27 32
7 27
15 20

10 45
2 15
38 42
15 42
32 41
26 35
42 45
14 43
6 33
13 14
19 45

6 38
32 35
23 38
21 30
6 26
6 28
24 38

output

1 6
3 5
1 4
and*kgou

說明:

對於20%的資料 n<=100,t<=1000

對於40%的資料 n<=10000,t<=100000

對於100%的資料 n<=5000000,t<=5000000,T<=10;

思路:

經過一番摸♂索,便會發現,要找到的那個學生只要是獨自佔有時間最長就好了,因為把這個學生趕走後,他獨自佔有的時間就回變成WQH大佬的空閒時間。所以只需求出來這個學生是誰就可以了!如果每個學生都沒有獨自佔有時間,那就是無解啦!(即每個時間段都被覆蓋了兩次!)

做法:

用差分陣列求出每個時間段的人數。 再用字首和求出每個時間段只被一個人佔用的時間是多少。 最後列舉每個人的佔用時間段,看誰獨自佔用時間最多就是它啦! 如果沒有人有獨自佔用時間,那就是無解啦!

程式碼很簡單:

#include<bits/stdc++.h>
using namespace std;
#define maxn 1000005

int n,t,T;
long long sum[maxn],l[maxn],r[maxn];
long long a[maxn],b[maxn],ansNum,ansT;

int main()
{
//	freopen("test11.out","w",stdout);
//	freopen("test11.in","r",stdin);
	cin>>T;
	while(T--){
		scanf("%d%d",&n,&t);
		for(int i=1;i<=n;i++){
			cin>>l[i]>>r[i];
			b[l[i]]++;b[r[i]]--;	
		}
		for(int i=1;i<=t;i++) a[i]=a[i-1]+b[i];
		for(int i=1;i<=t;i++) if(a[i] > 1) a[i]=0;
		for(int i=1;i<=t;i++) sum[i]=sum[i-1]+a[i];
		for(int i=1;i<=n;i++)
			if(sum[r[i]-1]-sum[l[i]-1] > ansT){
				ansT=sum[r[i]-1]-sum[l[i]-1];
				ansNum=i;
			}
		if(ansNum==0 && ansT==0)
			printf("and*kgou\n");
		else
			cout<<ansNum<<" "<<ansT<<endl;		
		ansNum=0;ansT=0;
		memset(b,0,sizeof(b));
	}
	return 0;
}

寫在後面:

這是本蒟蒻第一次出題,出不了太高妙的題。 自己出資料的時候經歷了很多磨♂難,明白了出資料也是充滿艱辛的! 不過自己出題還真是挺有趣♂的。 挺難忘的一次經歷!