考慮最暴力的做法,實際上就是列舉選中區間的左右端點,然後用點分判斷選出的點構成的合法路徑和未選中的點構成的合法路徑的大小。
如果再優化一點可以,列舉其中乙個端點,另乙個端點動態的維護,有點類似動態點分的樣子。
這麼做的瓶頸在於列舉端點。首先如果右端點如果右移的話,那麼滿足條件的區間左端點的位置實際上是單調不降的。如果我們能預處理出某個東西,然後o(1)的判斷, 那麼問題就解決了。
首先如果是工業點權值為1,農業為-1。那麼如果一條路徑的點權和為0,那麼就是一條合法路徑。利用點分治,可以求出ans[i]。ans[i]表示以點i為端點的路徑中有多少是合法路徑。
那麼乙個區間的答案能否直接表示成ans[r]-ans[l-1]呢?
] 會得到上圖三種合法路徑,但是如果選中的是[l,r]那麼只有1是合法的。
但是我們發現2,3兩種路徑在計算選中區間和未選中區間答案的時候都被計算了一次,所以可以直接比較an
s[r]
−ans
[l−1
] 與su
m−(a
ns[r
]−an
s[l−
1]) 大小。再利用單調性就可以o(
n)的統計答案了
這道題一上來的感覺就是cdq分治,關鍵是怎麼統計矩形中不同矩形的個數。
有兩個思路:
思路1:來自出題人。
統計矩形中的不容易統計,於是我們轉化成統計矩形外的。把矩形外的區域分成八部分計算,即∑x
2[i]
+∑x1
[i]>x2
+∑y2[i]
+∑y1
[i]>y2
−∑x2[i]
andy
2[i]
−∑x2[i]
andy
1[i]
>y2
−∑x1
[i]>x2
andy
2[i]
−∑x1
[i]>x2
andy
1[i]
>y2
其中一位的可以直接統計,二維的其實就是(時間,x,y)用cdq求三維偏序。
思路2:
把矩形的左邊界和右邊界分開考慮。乙個矩形中與他相交的矩形個數其實就是他右邊界左邊所有範圍[y1,y2]中左邊界的個數-左邊界左邊所有範圍[y1,y2]中右邊界的個數。
考慮如何維護左邊界的個數。我們可以統計區間中所有的左邊界,然後減去全部在y1上方的矩形和全部在y2下方的矩形。這個某乙個位置上下方的矩形個數可以用線段樹或者樹狀陣列維護。
右邊界也是同樣的道理。
直接一遍cdq就可以了。
#include
#include
#include
#include
#include
#define n 500003
using namespace std;
int cnty,cntx,x[n],y[n],sz,cnt,n;
struct seg
void clear(int now)
void pushdown(int now)
if (delta[now])
}void qjchange(int now,int l,int r,int ll,int rr,int v)
pushdown(now);
int mid=(l+r)/2;
if (ll<=mid) qjchange(now<<1,l,mid,ll,rr,v);
if (rr>mid) qjchange(now<<1|1,mid+1,r,ll,rr,v);
}int fp(int now,int l,int r,int
x)}upl,downl,upr,downr;
struct dataq[n];
struct nodea[n];
int cmp(data a,data b)
if (q[i].opt==2)
if (q[i].opt==3)
if (q[i].opt==4)
}if (q[i].pd==0)
if (q[i].opt==6) }}
sort(q+l,q+r+1,cmp1);
cdq(l,mid); cdq(mid+1,r);
}int main()
if (s[1]=='d')
if (s[1]=='q')
}sort(x+1,x+cntx+1); sort(y+1,y+cnty+1);
cntx=unique(x+1,x+cntx+1)-x-1;
cnty=unique(y+1,y+cnty+1)-y-1;
for (int i=1;i<=sz;i++)
cdq(1,sz);
for (int i=1;i<=sz;i++)
if (q[i].opt==5)
}
省隊集訓Round2 DAY2
首先字首和的變化一定是連續的。那麼對於每個區間,我們找到他最大值和最小值所在的位置,如果k在最小最大值之間,那麼一定可以從最小值最大值位置所構成的區間中得到。那麼根據單調性二分就可以了。每次二分出乙個位置用杜教篩計算一下。對於最大值最小值所在的位置可以打表啊。這道題以前做過乙個靜態的,就是樹在開始的...
省隊集訓Round2 DAY3
用splay維護權值有序。每次加入乙個人,貪心的選出前i 1個人中要求最小的vi 1,判斷能否滿足,如果能滿足就把這vi 1個人的權值 1,剩下的人不需要他們的支援,那麼都賦值成0,並且把這些點移動到平衡樹中0所在的位置 如果不能滿足就直接在平衡樹中加入乙個 1.要求每乙個時間每條邊只能有乙個人經過...
省隊集訓Round3 DAY4
講序列分成三部分,大根堆,緩衝區s,小根堆。任意時刻保證mid在緩衝區中,並且盡量保證大根堆和小根堆的大小盡量相等。均攤時間複雜度為o 首先打表發現sg函式的規律。1 p為奇數,從0開始sg值01迴圈 要統計區間的答案其實就是統計區間中sg值為1的數的個數。用線段樹維護區間中偶數 奇數的個數其實就是...