1. 程式人生 > >天天愛吃雞

天天愛吃雞

ons 技術 void hid == clas node ins ble

天天愛吃雞

如果我們以子彈為研究對象,來尋找合法的木板,問題將會變得很麻煩,不妨反過來考慮,每一個木板只會對第s個打到他的子彈有貢獻,於是問題就變成了去檢查訊第k大的數字,主席樹維護即可。

技術分享圖片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int inf=2e5+10;
 4 int n,m;
 5 struct board{
 6     int l,r,s;
 7     void read(){
 8         scanf("%d%d%d",&l,&r,&s);
9 } 10 }b[inf]; 11 struct node{ 12 int ls,rs,siz,bel; 13 }t[inf*20]; 14 int max_r,rt[inf],siz; 15 int ans[inf]; 16 vector<int>S[inf]; 17 void insert(int l,int r,int o,int x){ 18 t[o].siz++; 19 // printf("%d %d %d\n",l,r,t[o].siz); 20 if(l==r)return ; 21 int mid=(l+r)>>1
; 22 if(x<=mid){ 23 if(t[t[o].ls].bel!=t[o].bel){ 24 siz++; 25 t[siz]=t[t[o].ls]; 26 t[siz].bel=t[o].bel; 27 t[o].ls=siz; 28 } 29 insert(l,mid,t[o].ls,x); 30 } 31 else { 32 if(t[t[o].rs].bel!=t[o].bel){
33 siz++; 34 t[siz]=t[t[o].rs]; 35 t[siz].bel=t[o].bel; 36 t[o].rs=siz; 37 } 38 insert(mid+1,r,t[o].rs,x); 39 } 40 } 41 int query(int l,int r,int o1,int o2,int x){ 42 if(l==r)return l; 43 int tmp=t[t[o2].ls].siz-t[t[o1].ls].siz,mid=(l+r)>>1; 44 // printf("%d %d %d %d\n",t[t[o2].ls].siz,t[t[o1].ls].siz,l,r); 45 if(tmp>=x)return query(l,mid,t[o1].ls,t[o2].ls,x); 46 else return query(mid+1,r,t[o1].rs,t[o2].rs,x-tmp); 47 } 48 int main() 49 { 50 freopen("shooting.in","r",stdin); 51 freopen("shooting.out","w",stdout); 52 scanf("%d%d",&n,&m); 53 for(int i=1;i<=n;i++)b[i].read(),max_r=max(max_r,b[i].r); 54 for(int i=1;i<=m;i++){ 55 int x; 56 scanf("%d",&x); 57 S[x].push_back(i); 58 } 59 m++; 60 for(int i=1;i<=max_r;i++){ 61 int sz=S[i].size(); 62 rt[i]=++siz; 63 t[rt[i]]=t[rt[i-1]]; 64 t[rt[i]].bel=rt[i]; 65 for(int j=0;j<sz;j++){ 66 insert(1,m,rt[i],S[i][j]); 67 } 68 } 69 for(int i=1;i<=n;i++) 70 ans[query(1,m,rt[b[i].l-1],rt[b[i].r],b[i].s)]++; 71 for(int i=1;i<m;i++)printf("%d\n",ans[i]); 72 return 0; 73 }
View Code

天天愛吃雞