挺简单的
2025-12-28 21:04:11
发布于:广东
34阅读
0回复
0点赞
原题:P7424 [THUPC 2017] 天天爱射击
肥肠简单,请先自行构思。
如果把每个子弹当作询问的话,处理射击后的每个木板的状况会很麻烦。考虑整体二分,综上所述只能把木板当作询问,直接二分第几发子弹射出后木板破碎,这就在树状数组的解决范围内了,统计对每个木板来说 发子弹发出后有多少打在这个木板区间内即可 check.最后确定答案时,把贡献算在最后这发打坏木板的子弹上就行了。小 Trick: 整体二分时将值域加一,这样完成不了的询问就会落在值域加一的答案区间,这题中可以将这些答案忽略掉因为加到第 个子弹的答案不算数(只有 发)不会输出。
#include<bits/stdc++.h>
using namespace std;
#define int long long
int read(){
int x=0,f=1,ch=getchar_unlocked();
for(;!isdigit(ch);ch=getchar_unlocked())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar_unlocked())x=(x<<3)+(x<<1)+(ch^48);
return x*f;
}
void write(int x){
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar((x%10)|48);
}
struct xyl{
int l,r,k;
}q[200005],q1[200005],q2[200005];
int n,m,a[200005],ans[200005],tree[200005];
void add(int x,int k){for(int i=x;i<=200000;i+=i&(-i))tree[i]+=k;}
int sum(int x){
int res=0;
for(int i=x;i;i-=i&(-i))res+=tree[i];
return res;
}
void solve(int l,int r,int ql,int qr){
if(ql>qr)return;
if(l==r){ans[l]+=qr-ql+1;return;}
int cnt1=0,cnt2=0,mid=l+r>>1;
bool b1=0,b2=0;
for(int i=l;i<=mid;++i)add(a[i],1);
for(int i=ql;i<=qr;++i){
int t=sum(q[i].r)-sum(q[i].l-1);
if(q[i].k<=t)q1[++cnt1]=q[i],b1=1;
else q[i].k-=t,q2[++cnt2]=q[i],b2=1;
}
for(int i=l;i<=mid;++i)add(a[i],-1);
for(int i=1;i<=cnt1;++i)q[ql+i-1]=q1[i];
for(int i=1;i<=cnt2;++i)q[ql+cnt1+i-1]=q2[i];
if(b1)solve(l,mid,ql,ql+cnt1-1);
if(b2)solve(mid+1,r,ql+cnt1,qr);
}
signed main(){
n=read(),m=read();
for(int i=1;i<=n;++i)q[i]={read(),read(),read()};
for(int i=1;i<=m+1;++i)a[i]=i==m+1?1:read();
solve(1,m+1,1,n);
for(int i=1;i<=m;++i)write(ans[i]),putchar('\n');
return 0;
}
时间复杂度:
全部评论 3
题解GO们不会知道此题跑的最慢的哪位才是大佬
2026-01-13 来自 广东
0为何有人抄我题解然后比我快1ms
2026-01-13 来自 广东
0%%%
写了篇主席树单 log 解法,但是比你慢 4 倍(((
2026-01-05 来自 广东
0好家伙原来有主席树做法(
2026-01-06 来自 广东
0不用%这题用整体二分是轮椅
2026-01-06 来自 广东
0OI特有的单log比双log慢
2026-01-06 来自 广东
0













有帮助,赞一个