[LOJ2402] "THUPC 2017" love every day shooting / Shooting (whole half)

Click here to see the problem surface

Roughly meaning of the questions: There \ (n \) intervals, each interval has a weight, in power value becomes \ (0 \) disappears. Each time will cover all sections of the right to a certain position value minus \ (1 \) , seeking each time interval the number of disappeared at this moment.

Overall dichotomy

This question is obviously a whole half naked to the bar.

We put planks together and bullets to time as a keyword half.

Each time less than or equal to enumerate all \ (MID \) bullets on the tree to its position corresponding to an array of single-point modification value plus \ (1 \) .

Then, the enumeration of wood, it covers the query interval Interval how many bullets, bullet if the number is greater than equal to its weight, it is thrown into the left section, otherwise it weight minus the number of bullets, and then thrown into the right range.

Note that the upper bound for the half \ (m + 1 \) , because there may be no wood to eventually disappear.

Code

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 200000
using namespace std;
int n,m,ans[N+5];struct data {int x,y,k;}s[2*N+5],p1[2*N+5],p2[2*N+5];
class FastIO
{
    private:
        #define FS 100000
        #define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
        #define pc(c) (C==E&&(clear(),0),*C++=c)
        #define tn (x<<3)+(x<<1)
        #define D isdigit(c=tc())
        int T;char c,*A,*B,*C,*E,FI[FS],FO[FS],S[FS];
    public:
        I FastIO() {A=B=FI,C=FO,E=FO+FS;}
        Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
        Tp I void write(Ty x) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);}
        Tp I void writeln(Con Ty& x) {write(x),pc('\n');}
        I void clear() {fwrite(FO,1,C-FO,stdout),C=FO;}
}F;
class TreeArray//树状数组
{
    private:
        int v[N+5];
    public:
        I void Upt(RI x,CI y) {W(x<=n) v[x]+=y,x+=x&-x;}
        I int Qry(RI x) {RI t=0;W(x) t+=v[x],x-=x&-x;return t;}
}T;
I void Solve(CI L,CI R,CI l,CI r)//整体二分
{
    if(l==r) {for(RI i=L;i<=R;++i) s[i].y&&(++ans[l]);return;}RI i,t,t1=0,t2=0;int mid=l+r>>1;//边界统计答案
    for(i=L;i<=R;++i) if(!s[i].y) s[i].k<=mid?(T.Upt(s[i].x,1),p1[++t1]=s[i]):p2[++t2]=s[i];else break;//枚举子弹
    for(;i<=R;++i) s[i].k<=(t=T.Qry(s[i].y)-T.Qry(s[i].x-1))?p1[++t1]=s[i]:(s[i].k-=t,p2[++t2]=s[i]);//枚举木板
    for(i=1;i<=t1;++i) !p1[i].y&&(T.Upt(p1[i].x,-1),0),s[L+i-1]=p1[i];for(i=1;i<=t2;++i) s[L+t1+i-1]=p2[i];//重新填充数组,同时注意清空树状数组
    Solve(L,L+t1-1,l,mid),Solve(L+t1,R,mid+1,r);//继续递归求解
}
int main()
{
    RI i;for(F.read(n),F.read(m),i=1;i<=n;++i) F.read(s[m+i].x),F.read(s[m+i].y),F.read(s[m+i].k);//读入木板
    for(i=1;i<=m;++i) F.read(s[i].x),s[i].k=i;//读入子弹
    for(Solve(1,n+m,1,m+1),i=1;i<=m;++i) F.writeln(ans[i]);return F.clear(),0;//输出答案
}

Guess you like

Origin www.cnblogs.com/chenxiaoran666/p/LOJ2402.html