\(\mathtt \)
題意概要:一條直線上有 \(n+1\) 個點和 \(n\) 條道路,每條道路連通相鄰兩個點。在 \(q\) 個時刻內,每個時刻有如下兩種操作之一:
\(n,q\leq 3\times 10^5\),時限 \(5s\)
切了前兩題讓我還以為今年apio能ak的說,這題沒切主要是因為沒有想到可以將若干段區間的和變為所有右端點的座標減去所有左端點的座標,之前一直在想如何計算修改對答案的貢獻來著
在這題裡,連線即一段存在區間的左端點,減去當前時刻 \(t\),斷開即一段區間的右端點,加上當前時刻 \(t\)。特別的,當一次詢問時若他們之間連通,則需要再次強行加上當前時刻 \(t\)。
考慮切換道路 \((x,x+1)\),找到 \(x\) 往左走的最遠端 \(l\),與 \(x+1\) 往右走的最遠端 \(r\),則這次切換的影響為:左端點在 \([l,x]\) 內,且右端點在 \([x+1,r]\) 內的所有區間。
放到平面上去就是乙個矩形,而詢問就是詢問這個平面上的乙個點。有時間、\(x\)、\(y\)共三維,用 \(cdq+bit\) 可做到 \(o(n\log^2n)\)。
至於找到每個位置向左向右的最遠點,用 \(set\) 維護一下所有的極長道路區間即可
//loj-3146
#include using namespace std;
#define lb(x) (x&(-x))
template inline void read(_tp&x)
const int n = 301000;
int n;
namespace wk
inline int qry(int x) }
struct node q[n*4], b[n*4];
int ans[n], qs, tot;
void qwq(int l, int r) else
} for(int i=l;i<=m;++i)
if(q[i].op == 0)
bit::add(q[i].y, -q[i].v);
for(int i=l;i<=r;++i)
q[i] = b[i]; }
void work()
inline void add_modify(int x0, int x1, int y0, int y1, int v) ;
q[++tot] = (node) ;
q[++tot] = (node) ;
q[++tot] = (node) ;
} inline void add_query(int x, int y, int vl) ;
ans[qs] = vl; }}
char str[n]; bool st[n];
int q;
typedef pairpii;
set c;
set :: iterator it, itr;
#define ins insert
#define ers erase
namespace bit
inline int qry(int l, int r)
}int main()
for(int i=1,j;(j=i)<=n;i=j+1)
char opt[7];
int x, y;
for(int i=1;i<=q;++i) else
} else
} wk::work();
return 0;
}
APIO2019簡要題解
看到這種題,我們肯定會想到 x,y 一定有迴圈 我們要找到迴圈節的長度 推一下發現 x 的迴圈節長為 frac 等一下,t 是整數,所以迴圈節長為 frac y 的迴圈節長為 b 所以 x,y 的迴圈節長為 lcm frac,b frac 對每個時間段對迴圈節長取模進行區間覆蓋即可 用了 int12...
P5445 APIO2019 路燈(樹套樹)
p5445 apio2019 路燈 轉化為平面上的座標 x,y x,y se t set維護連續區間.用樹套樹維護矩陣加法,單點查詢。注意維護矩陣差分的時候,x,y,v 是對 x,y n 1,n 1 的矩陣做出貢獻 include include include include define ri ...
洛谷 P5445 路燈
題意見洛谷。首先考慮實時維護 forall i,j in 1,n 目前有多少時刻滿足能從 i 到達 j 顯然,i 能到達 j 當且僅當 i,j 在同乙個亮燈連續段裡。將當前狀態剖成若干個極大亮燈連續段,那麼能否到達關於 i,j 兩維的函式應該是由這些連續段,每段分別在 i 軸和 j 軸上作為兩條鄰邊...