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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

监视任务

發布時間:2023/12/3 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 监视任务 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

來源:牛客網

時間限制:C/C++ 2秒,其他語言4秒
空間限制:C/C++ 131072K,其他語言262144K
64bit IO Format: %lld

題目描述

𝑅𝑒𝑘𝑖在課余會接受一些民間的鷹眼類委托,即遠距離的狙擊監視防衛。
𝑅𝑒𝑘𝑖一共接到了𝑚份委托,這些委托與𝑛個直線排布的監視點相關。 第𝑖份委托的內容為:對于區間[𝑙𝑖,
𝑟𝑖]中的監視點,至少要防衛其中的𝑘𝑖個。 𝑅𝑒𝑘𝑖必須完成全部委托,并且希望選取盡量少的監視點來防衛。

輸入描述:
第一行,兩個正整數𝑛,𝑚。
接下來𝑚行,每行三個整數𝑙𝑖,𝑟𝑖,𝑘𝑖。
輸出描述:
一行,一個整數,即所需防衛的最少監視點數量。
示例1
輸入
復制

11 5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1

輸出
復制

6

備注:

對于10%的數據,𝑛 ≤ 10。 對于20%的數據,𝑛 ≤ 20。 對于30%的數據,𝑛,𝑚 ≤ 30。 對于60%的數據,𝑛,𝑚 ≤ 1000。 對于100%的數據,𝑛 ≤ 500000,𝑚 ≤ 1000000,𝑙𝑖 ≤ 𝑟𝑖,𝑘𝑖 ≤ 𝑟𝑖?𝑙𝑖+1

題解:

貪心+線段樹
我們先將給的m個區間進行排序,按照右端點值從小到大排
然后對每個區間值查詢監視點的數量,如果不滿足要求就填充,記得要盡可能的給區間的右側填充,因為這樣更有利于后面的區間能用上
比如[1,3]和[3,6],兩個區間各需要一個監視點,我們我們給[1,3]按上一個,盡可能在右側安裝,也就是點3,這樣查詢[3,6]時我們發現已經有了,就不用給[3,6]再安裝了
區間修改操作涉及到了線段樹
那在線段樹區間修改的時候,怎么能先優先更新右側?
很簡單,我們在更新是優先更新右節點

if(r>mid)val=update(id*2+1,mid+1,R,l,r,val);if(l<=mid)val=update(id*2,L,mid,l,r,val);

代碼中是先更新id*2+1即右節點,這樣就會優先在右側填充,如果兩個語句反過來,就是優先填充左側
有兩種寫法(一種用到pushdown的區間修改,另一種單純只用到單點修改)對了,每個坐標點只能放置一個監視點。。

代碼:

#include<set> #include<map> #include<stack> #include<queue> #include<vector> #include<string> #include<time.h> #include<math.h> #include<stdio.h> #include<iostream> #include<string.h> #include<stdlib.h> #include<algorithm> #include<functional> using namespace std; #define ll long long #define inf 1000000000 #define mod 1000000007 #define maxn 500005 #define lowbit(x) (x&-x) #define eps 1e-9 struct node {int l,r,k; }a[maxn*2]; int n,m,sum[maxn*5],lazy[maxn*5]; bool comp(node a,node b) {return a.r<b.r; } void pushdown(int l,int r,int id) {if(lazy[id]){int mid=(l+r)/2;lazy[id*2]=1;sum[id*2]=mid-l+1;lazy[id*2+1]=1;sum[id*2+1]=r-mid;lazy[id]=0;} } int update(int id,int L,int R,int l,int r,int val) {if(val<=0)return 0;if(L>=l && R<=r){if(R-L+1-sum[id]<=val)//需要布置監視點 (即便當前全部布滿也不能達到要求){val-=R-L+1-sum[id];//還需要的監視點 lazy[id]=1;sum[id]=R-L+1;//全部布滿return val;//還需要布滿的數量 }}pushdown(L,R,id);int mid=(L+R)/2;if(r>mid)val=update(id*2+1,mid+1,R,l,r,val);if(l<=mid)val=update(id*2,L,mid,l,r,val);sum[id]=sum[id*2]+sum[id*2+1];return val; } int query(int id,int L,int R,int l,int r) {if(L>=l && R<=r)return sum[id];pushdown(L,R,id);int mid=(L+R)/2,res=0;if(l<=mid)res+=query(id*2,L,mid,l,r);if(r>mid)res+=query(id*2+1,mid+1,R,l,r);return res; } int main(void) {int i;scanf("%d%d",&n,&m);for(i=1;i<=m;i++)scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].k);sort(a+1,a+m+1,comp);for(i=1;i<=m;i++){int w=query(1,1,n,a[i].l,a[i].r);int w1=query(1,1,n,6,6);printf("%d~%d w=%d\n",a[i].l,a[i].r,w);//printf("%d~%d w=%d\n",6,6,w1);update(1,1,n,a[i].l,a[i].r,a[i].k-w);}printf("%d\n",query(1,1,n,1,n));return 0; } // 監視任務 運行/限制:898ms/2000ms #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; struct node {int l, r, k;bool operator<(const node& b)const {return r < b.r;} }a[1000005]; int sum[500005 << 2]; int book[500005]; void pushUp(int root) {sum[root] = sum[root << 1] + sum[root << 1 | 1]; } void build(int le, int rig, int root) {if (le == rig) {sum[root] = 0;return;}int mid = (le + rig) >> 1;build(le,mid,root<<1);build(mid+1,rig,root<<1|1);pushUp(root); } int query(int l, int r, int le, int rig, int root) {if (l <= le && r >= rig) {return sum[root];}int re = 0;int mid = (le + rig) >> 1;if (l <= mid) {re += query(l, r, le,mid,root<<1);}if (r > mid) {re += query(l, r, mid+1,rig,root<<1|1);}return re; } void update(int pos, int le, int rig, int root) {if (le == rig) {sum[root] = 1;return;}int mid = (le + rig) >> 1;if (pos <= mid) {update(pos, le,mid,root<<1);}else {update(pos, mid+1,rig,root<<1|1);}pushUp(root); } int main(){int n, m, ans;while (scanf("%d%d", &n, &m) != EOF) {ans = 0;memset(book, 0, sizeof(book));for (int i = 0; i < m; i++) {scanf("%d%d%d",&a[i].l, &a[i].r, &a[i].k);}build(1, n, 1);sort(a, a + m);for (int i = 0; i < m; i++) {int pos = a[i].r;//區間右邊界int cnt = query(a[i].l,a[i].r, 1, n, 1);//查詢該區間已經被防衛的點的數量while (cnt < a[i].k) {while (book[pos]) pos--;//從右向左找位置加防衛book[pos] = 1;update(pos, 1, n, 1);ans++;cnt++;}}printf("%d\n", ans);}return 0; }

總結

以上是生活随笔為你收集整理的监视任务的全部內容,希望文章能夠幫你解決所遇到的問題。

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