省隊集訓day6 C

2022-06-03 12:06:08 字數 1881 閱讀 2823

給定平面上的 n 個點, 其中有一些是紅的, 其他是藍的.現在讓你找兩條平行的直線, 使得在保證

不存在乙個藍色的點 被夾在兩條平行線之間,不經過任何乙個點, 不管是藍色點還是紅色點

的前提下,

被夾在平行線之間的紅色點個數最多

第1行: 乙個整數 n (1 <= n <= 1000)

第2..n+1行: 每行是乙個點的座標以及它的顏色.

座標用2個 絕對值<10^9

的整數表示

顏色用 'r' 或 'b' 表示

第1行: 僅乙個整數, 被夾在平行線之間的紅色點個數的最大值

40 0 r

0 1 b

1 1 r

1 0 b2

先考慮一下如果這兩條直線必須與x軸垂直怎麼做,我們先可以將所有點按x為第一關鍵字,y為第二關鍵字排序,在這個排好序的序列中找到最長的一段紅色就是答案了(用線段樹維護)

然後我們把座標系旋轉,如果y軸掃過了兩點連成的直線,則這兩個點的排名就會交換,旋轉一周交換的點對為o(n2)個,所以可以用乙個線段樹來維護區間最長紅點數,支援單點修改和查詢,複雜度o(n2logn)。

code:

1 #include2 #include3 #include4 #include5

#define maxn 1005

6using

namespace

std;

7int

n,m,a,b,ans,pos[maxn];

8char s[2

]; 9 inline int min(const

int &a,const

int &b)

13 inline int max(const

int &a,const

int &b)

17struct

pointpoint[maxn];

20 inline bool

cmp1(point a,point b)

24struct

lineline[maxn*maxn];

27 inline bool cmp2(const line &a,const line &b)

28 inline bool cmp(const line &a,const line &b)

29struct

seg

39 inline void modify(int k,int l,int r,int x,int

c) 41

int m=(l+r)>>1

; 42

if (x<=m) modify(ls,l,m,x,c); else modify(rs,m+1

,r,x,c);

43update(k);

44}

45}t;

46int

main()

52 sort(point+1,point+n+1

,cmp1);

53for (int i=1;i<=n;i++) for (int j=i+1;j<=n;j++)

54 line[++m]=(line);

55 sort(line+1,line+m+1

,cmp2);

56for (int i=1;i<=n;i++) t.modify(1,1

,n,i,point[i].col);

57 ans=t.val[1

]; 58

for (int i=1,j=1;i<=m;i=j)

66}

67 printf("

%d\n

",ans);

68return0;

69 }

省隊集訓DAY6

f i 表示以字元i結尾的字串的個數。那麼現在加入乙個字元產生的貢獻就是 字 符集大小 i 0f i 然後把這個答案賦值給這個字元對應的位置。考慮這麼做會不會產生相同的串?假設acbb,考慮插入第乙個b的影響會形成ab,cb,acb.那麼插入第二個b會形成abb,cbb,acbb發現這些都是新產生的...

省隊集訓Round3 DAY6

這道題應該是可以通過組合數直接計算的,但是我不會數學證明,所以就用了一種簡單粗暴的方式。an s 2 ic n,i c n n i an s 2 ic n,i 2 101 8 肯定不能直接列舉,如果要計算的話也需要用到lucas定理。觀察發現這題的模數比較小,所以從模數入手。考慮lucas定理。n ...

省隊集訓DAY2

假設我們列舉數列中長度為len的區間,那麼如何判斷兩個數列可以匹配呢?對於提取的數列從小到大排序,從大到小排序,然後兩兩配對,如果所有的都滿足 h 那麼就可以匹配。應該算是貪心吧。這樣做的時間複雜度是o n le n loglen 還是上面的思想,我們如何快速判斷呢?假設我們確定了提取出的區間數列,...