POJ 2352 star level

來源:互聯網
上載者:User

標籤:style   blog   http   color   os   io   for   art   

題目連結:

http://poj.org/problem?id=2352

題目大意:
對於每一顆星星來說,都有一個屬於自己的level,這個值為其他星星x,y座標均不大於本星星的個數。輸入時按先y由小到大,再x由小到大排列,無相同位置的星星

 

仔細一想其實這道題目根本不需要用到y,我是反向來思考的,構建一個儲存x座標由0到maxn的線段樹,因為最後一個星星肯定不可能x,y同時不大於其他星星,所

以從後面開始看,只計算比它x小或相等的星星的個數,用cnt[ans]++,來記錄成為ans水平的個數,再刪去這個點,繼續找上一個點對應的level

 

在這裡要注意的是數組的範圍,我就因為這個改了半天錯,第一次發現數組範圍定的不夠大也是WA

他這裡星星個數為15000,但是我們儲存的是x的座標,所以要看x最大達32000,所以用4*32000的大小儲存tree[],My Code裡懶得修改了就寫成了

#define N 15005
int cnt[N],num[2*N],tree[8*N],D,maxn;//開始我寫成的是4*N所以報錯T T

 1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 #define N 15005 5 int cnt[N],num[2*N],tree[8*N],D,maxn; 6  7 int max(int a,int b) 8 { 9     return a>b?a:b;10 }11 12 void update(int i)13 {14     for(;i^1;i>>=1)15         tree[i>>1]=tree[i]+tree[i^1];16 }17 18 int query(int a,int b)19 {20     int i=D+a-1,j=D+b+1,ans=0;21     for(;i^j^1;i>>=1,j>>=1)22     {23         if(~i&1) ans+=tree[i^1];24         if(j&1)  ans+=tree[j^1];25     }26     return ans;27 }28 29 int main()30 {31     int n,x[N],y;32     while(scanf("%d",&n)!=EOF){33         maxn=0;34         memset(num,0,sizeof(num));35         //memset(tree,0,sizeof(tree));36         for(int i=1;i<=n;i++){37             scanf("%d%d",&x[i],&y);38             maxn=max(maxn,x[i]);39             num[x[i]]++;40         }41         for(D=1;D<maxn+1+2;D<<=1);42         for(int i=1;i<=maxn+1;i++) tree[D+i]=num[i-1];43         for(int i=D-1;i>=1;i--) tree[i]=tree[i<<1]+tree[i<<1|1];44         for(int i=0;i<=n-1;i++) cnt[i]=0;45         //for(int i=1;i<=2*D-1;i++) printf("%d\n",tree[i]);46         for(int i=n;i>=1;i--){47            // printf("%d",query(1,x[i]+1));48             tree[D+x[i]+1]--;49             update(D+x[i]+1);50             cnt[query(1,x[i]+1)]++;51         }52         for(int i=0;i<n;i++) printf("%d\n",cnt[i]);53     }54     return 0;55 }

當然從前往後思考也是一樣的,那樣的話是不斷將x添入線段樹,這裡有一份是學長的代碼,果然比我反向思考的要簡潔好多,而且從他的代碼也得到了其實tree的底層在沒有

得到頂點的必要時,也是可以不必強求定位1<<n這種2的幾次方的大小的,而在這裡正好適用,因為每次找個數和只求到i^j^1即可(這個代表左右子樹);

代碼如下:

#include <cstdio>#include <cstring>const int maxn = 32010;int tree[maxn<<2],a[maxn];int N,D;void update(int i){    for(;i^1;i >>= 1){        tree[i>>1] = tree[i]+tree[i^1];    }}int query(int x,int y){    int i = D+x-1,j = D+y+1,ans = 0;    for(;i^j^1;i >>= 1,j >>= 1){        if(~i&1)    ans += tree[i^1];        if(j&1)     ans += tree[j^1];    }    return ans;}int main(){    while(scanf("%d",&N) != EOF){        memset(tree,0,sizeof(tree));        memset(a,0,sizeof(a));        D = 32010;        for(int i = 0;i < N;i++){            int x,y;            scanf("%d%d",&x,&y);            a[query(1,++x)]++;            tree[D+x]++;            update(D+x);        }        for(int i = 0;i < N;i++)    printf("%d\n",a[i]);    }    return 0;}
View Code

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.