BZOJ 2161 布娃娃 主席樹

2022-03-25 20:56:46 字數 1481 閱讀 3441

題面

想了乙個主席樹做法

我們把每個區間的兩個端點拆開

對$l,r$分別從小到大排序,分別從左到右依次把對應標號的$c_$插入到權值主席樹里

每次查詢$p_$,在排序後的$l,r$陣列上分別二分找到第乙個小於等於$p_$的位置

那麼$l,r$的主席樹相減之後就是能對$p_$產生貢獻的區間

在主席樹上二分即可

似乎平衡樹和線段樹的做法空間比我優秀得多..

1 #include 2 #include 3 #include 4

#define n1 100010

5#define m1 8000100

6using

namespace

std;78

const

int mod=19921228;9

struct

seg12

void update(int x,int l,int r,int r1,int &r2)

1315

if(l==r)

16int mid=(l+r)>>1;17

if(x<=mid) update(x,l,mid,ls[r1],ls[r2]);

18else update(x,mid+1

,r,rs[r1],rs[r2]);

19pushup(r2);20}

21int query(int k,int l,int r,int r1,int

r2)22

30}s;

3132

intn,mx;

33int

p[n1],c[n1];

34struct nodel[n1],r[n1];

35int cmp(node s1,node s2)

3637

void

make()

3846 sort(l+1,l+n+1,cmp); sort(r+1,r+n+1

,cmp);

47for(i=1;i<=n;i++) s.update(c[l[i].id],0,mx,s.root1[i-1

],s.root1[i]);

48for(i=1;i<=n;i++) s.update(c[r[i].id],0,mx,s.root2[i-1

],s.root2[i]);49}

50int

ans[n1];

5152

intmain()53

67 l=1,r=n,xr=0;68

while(l<=r) 69

74 ans[i]=s.query(i,0

,mx,s.root1[xl],s.root2[xr]);

75 (ret+=ans[i])%=mod;76}

77 printf("

%d\n

",ret);

78return0;

79 }

BZOJ2161 布娃娃(掃瞄線 線段樹)

題意 若干個點,對每個點求能覆蓋住它的線段的權值的第k大。正解顯然掃瞄線 線段樹,把每個線段拆成起點和終點,代表插入和刪除,線段樹維護第k大權值就好了。include include include include define rep i,a,b for int i a i b i define ...

bzoj 2597 石頭剪刀布

利用補集轉化建圖。可以得到ans c n,3 sigma c win i 2 具體的意思就是兩個勝場會破壞乙個三元環。之後展開,注意sigma win i n n 1 2,因為比賽場次是c n,2 個,因為寫成了n,一直wa include include include include inclu...

WC2007 bzoj2597 剪刀石頭布

description 在一些一對一遊戲的比賽 如下棋 桌球和羽毛球的單打 中,我們經常會遇到a勝過b,b勝過c而c又勝過a的有趣情況,不妨形象的稱之為剪刀石頭布情況。有的時候,無聊的人們會津津樂道於統計有多少這樣的剪刀石頭布情況發生,即有多少對無序三元組 a,b,c 滿足其中的乙個人在比賽中贏了另...