1103 - Castle Walls PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 64 MB In medieval times, knights commanded big armies of peasants. When they had to storm a castle they would line up neatly in front of the castle's wall and throw their grappling hooks over the walls. If one does not throw straight it can easily happen that two hooks cross, making it impossible for the two peasants to climb the wall. That's why every knight made his peasants practice a lot so that this would not happen in combat. Due to the recent Sir Arthur-Madam Claire Marriage (ACM), two peasant armies have to be merged. Traditionally Sir Arthur's peasants wear blue and Madame Claire's peasants wear red. When practicing together, both armies mix up in front of a castle's wall. On Sir Arthur's command, they all throw their grappling hooks. Due to their perfect training the hooks will never cross within an army, however it can happen that a hook thrown by a blue peasant crosses one thrown by a peasant of the red army. For statistical purposes, Sir Arthur now needs to find out how many grappling hooks have crossed so that he can measure how well their armies have already been merged. Given the positions of blue and red peasants as well as the positions they threw their grappling hooks at, determine how many distinct pairs of blue and red peasants crossed their hooks. If there are n blue and m red peasants, the positions in the line where the peasants are standing are numbered from 1 to n + m. The positions on the castle's wall are numbered from 1 to n + m as well, where position i is directly opposite of position i on the line the peasants are standing on. A grappling hook thrown from position i to j is said to cross another hook thrown from p to q if and only if (i < p and j ≥ q) or (i > p and j ≤ q) Grappling hooks of the same color will never cross each other, nor will two peasants occupy the same position on the line. However, two hooks (of different color) can be thrown to the same position in which case they are said to cross each other as well. Input Input starts with an integer T (≤ 8), denoting the number of test cases. Each case starts with a line containing two integers n and m, the number of blue and red peasants, respectively (1 ≤ n, m ≤ 105). The next n lines describe the blue peasants followed by m more lines for the red peasants. Each line consists of two integer i and j separated by a space, indicating the peasant's position i and the position j he threw his grappling hook to (1 ≤ i, j ≤ n + m). Output For each test case, print the case number and the number of distinct pairs of peasants whose grappling hooks are crossed. Sample Input Output for Sample Input 2 2 2 1 2 3 4 2 1 4 3 2 3 1 3 2 5 5 3 3 1 4 2 Case 1: 2 Case 2: 6
题意:说白了,就是,给你n+m对数(a,b);问,相交的有多少对。
A grappling hook thrown from position i to j is said to cross another hook thrown from p to q if and only if (i < p and j ≥ q) or (i > p and j ≤ q)
然后嘛,线段树还是树状数组就随便上了,我是用树状数组。(注意用long long ,我WA了一次)。
树状数组是一种能在logn复杂度完成单点修改,区间查询或者区间修改,单点查询的神器,由于代码简单,可拓展性高,用过的都说好!
关于树状数组的具体实现原理,这里就不多说了,请读者自行百度之。我记得POJ和HDU上有喝多这样的入门题。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 using namespace std; 6 7 #define N 200010 8 9 long long BIT[N]; 10 int maxn; 11 struct node{ 12 int x,y; 13 }p[N]; 14 15 bool cmp(const node &a,const node &b){ 16 if(a.x!=b.x) return a.x>b.x; 17 return a.y>b.y; 18 } 19 20 int lowbit(int x){ 21 return x&(-x); 22 } 23 24 void update(int key){ 25 for(int i=key;i<=maxn;i+=lowbit(i)) BIT[i]++; 26 } 27 28 int query(int key){ 29 int res=0; 30 for(int i=key;i>0;i-=lowbit(i)) res+=BIT[i]; 31 return res; 32 } 33 34 int main(){ 35 int t,cas=1; 36 cin>>t; 37 while(t--){ 38 int n,m; 39 cin>>n>>m; 40 for(int i=0;i<n+m;i++) scanf("%d%d",&p[i].x,&p[i].y); 41 sort(p,p+m+n,cmp); 42 memset(BIT,0,sizeof(BIT)); 43 maxn=n+m; 44 long long res=0; 45 for(int i=0;i<n+m;i++){ 46 res+=query(p[i].y); 47 update(p[i].y); 48 } 49 printf("Case %d: %lld\n",cas++,res); 50 } 51 return 0; 52 }