1. 程式人生 > >[SCOI2007]降雨量

[SCOI2007]降雨量

線段 ast 更改 clas return tmp 有一種 algo span

/*
首先對於年份進行離散化
然後我們的查詢有兩種,一個是查詢區間最大值,一個是查詢區間是否連續
更改操作有一種 單點修改
我的方法是用線段樹維護最大值,用並查集維護是否連通
抱歉沒有單點修改操作 QWQ 那麽我們在離散化的時候     添加虛節點表示是否會有未知的
用一個last數組記錄最遠的連續的位置
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#define M 200010
#define
lson l, mid , now << 1 #define rson mid + 1, r, now << 1 | 1 using namespace std; int read() { int nm = 0, f = 1; char c = getchar(); for(; !isdigit(c); c = getchar()) if(c == -) f = -1; for(; isdigit(c); c = getchar()) nm = nm * 10 + c - 0; return nm * f; }
int t[M << 2]; int y[M], lst[M], note[M], n, tmp, m, cnt; void modify(int l, int r, int now, int k, int ver) { if(l > k || r < k) return ; if(l == r) { t[now] = ver; return; } int mid = (l + r) >> 1; modify(lson, k, ver); modify(rson, k, ver); t[now]
= max(t[now << 1], t[now << 1 | 1]); } int query(int l, int r, int now, int ln, int rn) { if(l > rn || r < ln) return 0; if(l >= ln && r <= rn) return t[now]; int mid = (l + r) >> 1; return max(query(lson, ln, rn), query(rson, ln, rn)); } int main() { n = read(); for(int i = 1; i <= n; i++) { y[i] = read(); if(y[i] == y[i - 1] + 1) { note[++cnt] = y[i]; lst[cnt] = lst[cnt - 1]; } else { note[++cnt] = y[i] - 1; lst[cnt] = cnt; modify(1, 200000, 1, cnt, 0); note[++cnt] = y[i]; lst[cnt] = cnt; } modify(1, 200000, 1, cnt, read()); } cnt++; lst[cnt] = cnt; note[cnt] = 0x3e3e3e3e; modify(1, 200000, 1, cnt, 0); m = read(); while(m--) { int yn = read(), xn = read(); yn = lower_bound(note + 1, note + cnt + 1, yn) - note; xn = lower_bound(note + 1, note + cnt + 1, xn) - note; int ox = query(1, 200000, 1, xn, xn), oy = query(1, 200000, 1, yn, yn), om = query(1, 200000, 1, yn + 1, xn - 1); bool fx = (ox > 0), fy = (oy > 0); if((fx && om >= ox) || (fy && om >= oy) || (fx && fy && oy <= ox)){puts("false"); continue;} if(lst[xn] > yn || !fx || !fy){puts("maybe"); continue;} puts("true"); } return 0; }

[SCOI2007]降雨量