省隊集訓Round3 DAY4

2021-08-03 10:35:55 字數 3300 閱讀 2926

講序列分成三部分,大根堆,緩衝區s,小根堆。

任意時刻保證mid在緩衝區中,並且盡量保證大根堆和小根堆的大小盡量相等。

均攤時間複雜度為o(

首先打表發現sg函式的規律。

(1) p為奇數,從0開始sg值01迴圈

要統計區間的答案其實就是統計區間中sg值為1的數的個數。

用線段樹維護區間中偶數/奇數的個數其實就是維護01的個數。

如果加入的數為偶數,區間中數的奇偶性不變,否則奇偶性翻轉,維護翻轉標記即可。

(2) p為偶數,從0開始迴圈節為(p+1).若i%(p+1)==p,則sg[i]=2.

若i%(p+1)為奇數,則sg[i]為1,否則為0.

偶數的話需要分塊維護。

對於每個塊,維護%(p+1)為奇數的數和偶數的數。

並保證偶數與奇數的兩個餘數陣列有序。

對於修改,如果是整塊就直接修改塊的標記,散塊暴力修改。

對於查詢,散塊直接暴力記錄答案。整塊的話,因為我們要找i%(p+1)==p的個數,即sg為2的個數。根據p-delta的奇偶性,在兩個陣列中查詢。

因為模數為奇數,所以加入乙個數取模後奇偶性可能會發生改變,發生改變的一定是兩個陣列的乙個字尾,所以我們可以二分找到改變的位置。然後對delta的奇偶性分開討論即可。具體過程見**。

#include#include#include#include#define n 100003

using namespace std;

int a[n],n,m,p;

int cnt0[n*4],cnt1[n*4],delta[n*4],l[n],r[n],belong[n];

int calc(int x)

return x%2;

}void update(int

now)

void build(int

now,int l,int r)

intmid=(l+r)/2;

build(now

<<1,l,mid);

build(now

<<1|1,mid+1,r);

update(now);

}void change(int

now)

void pushdown(int

now)

}void qjchange(int

now,int l,int r,int ll,int rr)

intmid=(l+r)/2;

pushdown(now);

if (ll<=mid) qjchange(now

<<1,l,mid,ll,rr);

if (rr>mid) qjchange(now

<<1|1,mid+1,r,ll,rr);

update(now);

}int query(int

now,int l,int r,int ll,int rr)

struct datab[400];

void solve(int l,int r,int t,int x)

sort(b[t].even+1,b[t].even+b[t].cnt1+1);

sort(b[t].odd+1,b[t].odd+b[t].cnt0+1);

}int

get(int l,int r,int t)

return ans;

}int findl(int *a,int x,int val)

return ans;

}int findr(int *a,int x,int val)

return ans;

}int main()

else

}return 0;

}int blocksize=sqrt(n); int mx=0;

for (int i=1;i<=n;i++)

for (int i=1;i<=mx;i++)

sort(b[i].even+1,b[i].even+b[i].cnt1+1);

sort(b[i].odd+1,b[i].odd+b[i].cnt0+1);

}for (int i=1;i<=m;i++)

for (int j=l+1;j<=r-1;j++) b[j].delta+=x,b[j].delta%=(p+1);

solve(l1,r[l],l,x);

solve(l[r],r1,r,x);

}else

for (int j=l+1;j<=r-1;j++)

else

if (t1&1) ans^=1;

}ans^=get(l1,r[l],l);

ans^=get(l[r],r1,r);

printf("%d\n",ans?1:0);}}

}

省隊集訓Round2 DAY3

用splay維護權值有序。每次加入乙個人,貪心的選出前i 1個人中要求最小的vi 1,判斷能否滿足,如果能滿足就把這vi 1個人的權值 1,剩下的人不需要他們的支援,那麼都賦值成0,並且把這些點移動到平衡樹中0所在的位置 如果不能滿足就直接在平衡樹中加入乙個 1.要求每乙個時間每條邊只能有乙個人經過...

省隊集訓Round3 DAY6

這道題應該是可以通過組合數直接計算的,但是我不會數學證明,所以就用了一種簡單粗暴的方式。an s 2 ic n,i c n n i an s 2 ic n,i 2 101 8 肯定不能直接列舉,如果要計算的話也需要用到lucas定理。觀察發現這題的模數比較小,所以從模數入手。考慮lucas定理。n ...

省隊集訓Round2 DAY2

首先字首和的變化一定是連續的。那麼對於每個區間,我們找到他最大值和最小值所在的位置,如果k在最小最大值之間,那麼一定可以從最小值最大值位置所構成的區間中得到。那麼根據單調性二分就可以了。每次二分出乙個位置用杜教篩計算一下。對於最大值最小值所在的位置可以打表啊。這道題以前做過乙個靜態的,就是樹在開始的...