POJ 3067 – Japan

來源:互聯網
上載者:User

 

題目地址: http://poj.org/problem?id=3067

 

典型的樹狀數組題目。

 

    跟小學時做的連線題很像,問共有多少個交點。兩點間只能用線段連,並且假設不會有3條及以上的線段交於同一點。

    假設兩個點 (x1,y1)、(x2,y2)

    假若 y2 > y1 ,那麼此時,只要存在 x1 < x2 ,那麼就一定存在交點。

    即其中一點在另一點的左上方。

    所以我們先對 y從大到小排序,若y相等則對x從大到小排序。

    於是,對排序完成後的點集。從前往後遍曆。

每次遍曆:update(xi,1) ,橫座標為xi的數,數量加1 。 然後 query(xi - 1) ,其結果代表當前已記錄的、小於xi的橫座標總數,即得到該點左上方共有多少點。

 

    簡單來說,就是用樹狀數組來hash得到某個範圍內的數的總數。而這個範圍內某些數的數量是不斷更新的。

 

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int tree[10100];struct Point{int x,y;}p[1001000];int cmp(Point a,Point b){if(a.y==b.y) return a.x>b.x;return a.y>b.y;}int query(int x){int sum=0;while(x>0){sum+=tree[x];x-=x&-x;}return sum;}void update(int x,int n){while(x<=n){tree[x]++;x+=x&-x;}}int main(){int t,tt;int n,m,k;int sum,i;scanf("%d",&t);for(tt=1;tt<=t;tt++){scanf("%d%d%d",&n,&m,&k);for(i=1;i<=n;i++)tree[i]=0;sum=0;for(i=0;i<k;i++)scanf("%d%d",&p[i].x,&p[i].y);sort(p,p+k,cmp);for(i=0;i<k;i++){sum+=query(p[i].x-1);update(p[i].x,n);}printf("Test case %d: %d\n",tt,sum);}return 0;}

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.