日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Vijos P1103 校门外的树【线段树,模拟】

發布時間:2025/7/14 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vijos P1103 校门外的树【线段树,模拟】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

校門外的樹

描述

某校大門外長度為L的馬路上有一排樹,每兩棵相鄰的樹之間的間隔都是1米。我們可以把馬路看成一個數軸,馬路的一端在數軸0的位置,另一端在L的位置;數軸上的每個整數點,即0,1,2,……,L,都種有一棵樹。

由于馬路上有一些區域要用來建地鐵。這些區域用它們在數軸上的起始點和終止點表示。 已知任一區域的起始點和終止點的坐標都是整數,區域之間可能有重合的部分。現在要把這些區域中的樹(包括區域端點處的兩棵樹)移走。你的任務是計算將這些樹都移走后,馬路上還有多少棵樹。

格式

輸入格式

輸入的第一行有兩個整數:L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表馬路的長度,M代表區域的數目,L和M之間用一個空格隔開。接下來的M行每行包含兩個不同的整數,用一個空格隔開,表示一個區域的起始點和終止點的坐標。

輸出格式

輸出包括一行,這一行只包含一個整數,表示馬路上剩余的樹的數目。

樣例1

樣例輸入1

500 3 150 300 100 200 470 471

樣例輸出1

298

限制

每個測試點1s

來源

NOIP2005普及組第二題

題目鏈接:https://vijos.org/p/1103

思路:我估計也是智障了,這題明顯可以用模擬做,我TM竟然用線段樹寫,還RE了兩發,數組開了四倍你還要我怎樣,結果我開了八倍過了QAQ!

下面給出線段樹寫法:

1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=20010; 4 int n,m,ans=1; 5 struct Node 6 { 7 int l,r,sum; 8 }tree[N<<2]; 9 inline void buildtree(int l,int r,int pos) 10 { 11 tree[pos].l=l; 12 tree[pos].r=r; 13 if(l==r) 14 { 15 tree[pos].sum=1; 16 return; 17 } 18 int mid=(tree[pos].l+tree[pos].r)/2; 19 buildtree(l,mid,pos*2); 20 buildtree(mid+1,r,pos*2+1); 21 tree[pos].sum=tree[pos*2].sum+tree[pos*2+1].sum; 22 } 23 inline int query(int l,int r,int pos) 24 { 25 if(tree[pos].l==l&&tree[pos].r==r) 26 return tree[pos].sum; 27 if(tree[pos].r<l||tree[pos].l>r) 28 return 0; 29 return query(l,r,pos*2)+query(l,r,pos*2+1); 30 } 31 inline void update(int l,int r,int pos) 32 { 33 if(tree[pos].l==l&&tree[pos].r==r) 34 { 35 tree[pos].sum=0; 36 return; 37 } 38 if(tree[pos].l>r||tree[pos].r<l) 39 return; 40 update(l,r,pos*2); 41 update(l,r,pos*2+1); 42 tree[pos].sum=tree[pos*2].sum+tree[pos*2+1].sum; 43 } 44 int main() 45 { 46 cin>>n>>m; 47 buildtree(1,n,1); 48 for(int i=1;i<=m;i++) 49 { 50 int l,r; 51 scanf("%d%d",&l,&r); 52 if(!l) 53 ans=0; 54 update(!l?1:l,r,1); 55 } 56 cout<<query(1,n,1)+ans<<endl; 57 return 0; 58 }

模擬做法:簡單解釋一下,做法就是在【0,r】我們全部賦值為1,然后for一遍刪去重復部分,非常簡單,智障的我開始沒想到,但是如果這題L的數據是1000000,線段樹依然是正解!QAQ

下面給出模擬的代碼:

1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=10010; 4 int a[N]; 5 int main() 6 { 7 int n,m; 8 cin>>n>>m; 9 for(int i=0;i<=n;i++) 10 a[i]=1; 11 for(int i=1;i<=m;i++) 12 { 13 int l,r; 14 cin>>l>>r; 15 for(int j=l;j<=r;j++) 16 { 17 a[j]=0; 18 } 19 } 20 int sum=0; 21 for(int i=0;i<=n;i++) 22 { 23 if(a[i]) 24 sum++; 25 } 26 cout<<sum<<endl; 27 return 0; 28 }

?

總結

以上是生活随笔為你收集整理的Vijos P1103 校门外的树【线段树,模拟】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。