整体二分67pts
查看原帖
整体二分67pts
1471385
ZeyLam楼主2025/6/22 16:39

O.o求调。

#include<iostream>
#include<algorithm>
#include<vector>
#define lowbit(x) (x)&(-x)
using namespace std;
/*差分加二维数组统计陨石数量*/
/*值域是陨石雨的波数*/
int n,m,k,hasbeen=0,ans[300002]={0};
unsigned long long tree[300002]={0};
/*sate记录第i个国家分别在第几段*/
vector<int> satepos[300002];
struct query{
    int pos;
    unsigned long long collect;
}Q[300002],z[300002],y[300002];
struct rain{
    int l,r;
    unsigned long long a;
}R[300002];
void add(int l,int r,unsigned long long key){
    r++;bool bit=l>r;
    while(l<=m) tree[l]+=key,l+=lowbit(l);
    while(r<=m) tree[r]-=key,r+=lowbit(r);
    if(bit){int all=1;while(all<=m) tree[all]+=key,all+=lowbit(all);}
}//dui
unsigned long long sum(int x){unsigned long long res=0;while(x) res+=tree[x],x-=lowbit(x);return res;}/*dui*/
//注意存在无解的情况。
void solve(int ql,int qr,int l,int r){
    /*cout<<ql<<" "<<qr<<" "<<l<<" "<<r<<"\n";*/
    if(ql>qr) return;
    int mid=(l+r)>>1,zuo=0,you=0;
    while(hasbeen>mid) add(R[hasbeen].l,R[hasbeen].r,-R[hasbeen].a),hasbeen--;//dui
    while(hasbeen<mid) hasbeen++,add(R[hasbeen].l,R[hasbeen].r,R[hasbeen].a);//dui
    if(l==r){
        for(int i=ql;i<=qr;i++){
            unsigned long long res=0;for(int j:satepos[Q[i].pos]) res+=sum(j);
            if(Q[i].collect<=res) ans[Q[i].pos]=l;
        }
        return;
    }
    for(int i=ql;i<=qr;i++){
        unsigned long long res=0;for(int j:satepos[Q[i].pos]) res+=sum(j);
        /*cout<<i<<"|"<<res<<" ";*/
        if(res>=Q[i].collect) z[++zuo]=Q[i];
        else y[++you]=Q[i];
    }
    for(int i=1;i<=zuo;i++) Q[ql+i-1]=z[i];
    for(int i=1;i<=you;i++) Q[ql+zuo+i-1]=y[i];
    solve(ql,ql+zuo-1,l,mid);
    solve(ql+zuo,qr,mid+1,r);
}
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1,o;i<=m;i++) cin>>o,satepos[o].push_back(i);//dui
    for(int i=1;i<=n;i++) cin>>Q[i].collect,Q[i].pos=i;//dui
    cin>>k;for(int i=1;i<=k;i++) cin>>R[i].l>>R[i].r>>R[i].a;//dui
    /*一个国家可能有多个太空站 */
    solve(1,n,1,k);
    for(int i=1;i<=n;i++){
        if(ans[i]) cout<<ans[i]<<"\n";
        else cout<<"NIE\n";
    }
}
2025/6/22 16:39
加载中...