ZOJ - 1610 區間修改+暴力單點查詢
阿新 • • 發佈:2020-07-31
一、內容
題意:給定一個區間,初始值都是1,和幾組詢問,每次詢問將一段區間修改成某個值,最後求所有區間的和。
二、思路
- 用一個數組sum進行lazy標記和下放就可以了, 如果這個區間有多個數那麼這個區間sum[id] = -1, 若這個區間全部是一個相同的數那麼sum[id]=相同數。
- 進行pushdown()的時候,只需要講左右兒子區間賦值為sum[id], sum[id] = -1即可
- 最後query() 統計所有區間的和
三、程式碼
#include<bits/stdc++.h> using namespace std; #define sc(n) scanf("%c",&n) #define sd(n) scanf("%d",&n) #define pd(n) printf("%d\n", (n)) #define sdd(n,m) scanf("%d %d",&n,&m) #define sddd(n,m,z) scanf("%d %d %d",&n,&m,&z) #define pdd(n,m) printf("%d %d\n",n, m) #define ms(a,b) memset(a,b,sizeof(a)) #define all(c) c.begin(),c.end() #define pb push_back #define fi first #define se second #define mod(x) ((x)%MOD) #define lowbit(x) (x & (-x)) #define gcd(a,b) __gcd(a,b) typedef long long ll; typedef pair<int, int> PII; typedef vector<int> VI; typedef vector<string> VS; const int MOD = 1e9 + 7; const double eps = 1e-9; const int inf = 0x3f3f3f3f; const int maxn = 8e3 + 5; int n, color[maxn << 2], vis[maxn << 2], last, x, y, c; void pushdown(int id) { if (color[id] == -1) return; color[id << 1] = color[id << 1 | 1] = color[id]; color[id] = -1; } void update(int id, int l, int r, int x, int y, int c) { if (x <= l && y >= r) { color[id] = c; return; } pushdown(id); int m = (l + r) >> 1; if (x <= m) update(id << 1, l, m, x, y, c); if (y > m) update(id << 1 | 1, m + 1, r, x, y, c); } void query(int id,int l,int r) { if (l == r) { if (color[id] != -1 && color[id] != last) { vis[color[id]]++; } //-1也要記錄 沒有顏色 last = color[id]; return; } pushdown(id); int mid = (l + r) >> 1; query(id << 1, l, mid); query(id << 1 | 1, mid + 1, r); } int main() { //freopen("in.txt", "r", stdin); //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); while (sd(n) != EOF) { ms(color, -1); ms(vis, 0); while (n--) { sddd(x, y, c); update(1, 1, 8000, x + 1, y, c); } query(1, 1, 8000); last = -1; for (int i = 0; i <= 8000; i++) { if (vis[i]) printf("%d %d\n", i, vis[i]); } printf("\n"); } return 0; }