麗娃河的狼人傳說
Time limit per test: 1.0 seconds
Time limit all tests: 1.0 seconds
Memory limit: 256 megabytes
麗娃河是華師大著名的風景線。但由於學校財政緊缺,麗娃河邊的路燈年久失修,一到晚上就會出現走在河邊要打着手電的情況,不僅非常不方便,而且影響安全:已經發生了大大小小的事故多起。
方便起見,麗娃河可以看成是從 1 到 n 的一條數軸。爲了美觀,路燈只能安裝在整數點上,每個整數點只能安裝一盞路燈。經專業勘測,有 m 個區間特別容易發生事故,所以至少要安裝一定數量的路燈,
請問至少還要安裝多少路燈。
Input
第一行一個整數 T (1≤T≤300),表示測試數據組數。
對於每組數據:
第一行三個整數 n,m,k (1≤n≤103,1≤m≤103,1≤k≤n)。
第二行 k 個不同的整數用空格隔開,表示這些位置一開始就有路燈。
接下來 m 行表示約束條件。第 i 行三個整數 li,ri,ti 表示:第 i 個區間 [li,ri] 至少要安裝 ti 盞路燈 (1≤li≤ri≤n,1≤ti≤n)。
Output
對於每組數據,輸出 Case x: y。其中 x 表示測試數據編號(從 1 開始),y 表示至少要安裝的路燈數目。如果無解,y 爲 −1。
思路:對每個區間查詢是不是滿足要求,不滿足要求就要加燈。可以很容易想到是個單點更新區間查詢和。。。然後就寫了個樹狀數組。。。不足加燈是個單點更新,然後處理之前是查詢。。兩個注意的點。。排序是按r的升序排。。這考慮到對後面的貢獻,來神還是強2333我一開始是按l升序後來感覺不對。第二點是你在插燈的時候要先把已經有的燈數去了然後在沒有燈的地方插燈。。想了想我連這裏都錯了 還是蠢啊。。
不過聽czh大神說就直接一個一個加起來也能對2333
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<vector>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<map>
using namespace std;
//thanks to pyf ...
#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define mp(x,y) make_pair(x,y)
typedef pair<int, int> PII;
typedef long long ll;
const int N = 1e6 + 5;
struct Seg
{
int l, r;
int need;
} s[N];
int n, m, k;
int vis[N];
int a[N];
bool cmp(Seg a, Seg b)
{
return a.r < b.r || (a.r == b.r && a.l > b.l);
}
int lowbit(int x)
{
return x & (-x);
}
void update(int pos, int val)
{
while (pos <= n)
{
a[pos] += val;
pos += lowbit(pos);
}
}
int query(int pos)
{
int res = 0;
while (pos > 0)
{
res += a[pos];
pos -= lowbit(pos);
}
return res;
}
int main()
{
int T;
scanf("%d", &T);
int ka = 0;
while (T--)
{
CLR(vis, 0);
CLR(a, 0);
CLR(s, 0);
scanf("%d%d%d", &n, &m, &k);
for (int i = 0; i < k; i++)
{
int pos;
scanf("%d", &pos);
vis[pos] = 1;
update(pos, 1);
}
for (int i = 0; i < m; i++)
scanf("%d%d%d", &s[i].l, &s[i].r, &s[i].need);
sort(s, s + m, cmp);
int ans = 0;
int flag = 0;
for (int i = 0; i < m; i++)
{
int l = s[i].l, r = s[i].r, need = s[i].need;
if (query(r) - query(l - 1) >= need)
continue;
else if (r - l + 1 < need)
{
flag = 1;
break;
}
else
{
need -= (query(r) - query(l - 1));
for (int j = r; j >= l; j--)
{
if (!vis[j])
{
vis[j] = 1;
need -- ;
ans ++;
update(j, 1);
}
if (!need)
break;
}
}
}
if (flag)
printf("Case %d: -1\n", ++ka);
else
printf("Case %d: %d\n", ++ka, ans);
}
}