題面
想了乙個主席樹做法
我們把每個區間的兩個端點拆開
對$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 滿足其中的乙個人在比賽中贏了另...