题目链接:MET-Meteors
显然这个东西具有二分性。
但是一个一个二分太慢了,我们观察可以发现 可以整体二分,于是整体二分一下即可,不过比较卡常。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
typedef long long LL;
const int N=3e5+10,M=N<<1;
int n,m,k,cl[N],cr[N],ca[N],res[N]; LL d[M];
struct node{int id,need;}t[N],st[M]; vector<int> v[N];
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read(){
int x=0,f=1; char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;
}
inline void insert(int x,int v){for(;x<=2*m;x+=x&(-x)) d[x]+=v;}
inline LL ask(int x){LL s=0; for(;x;x-=x&(-x)) s+=d[x]; return s;}
void solve(int l,int r,int x,int y){
if(l==r){for(int i=x;i<=y;i++) res[t[i].id]=l; return ;}
int mid=l+r>>1; int tl=0,tr=n;
for(int i=l;i<=mid;i++) insert(cl[i],ca[i]),insert(cr[i]+1,-ca[i]);
for(int i=x;i<=y;i++){
LL s=0;
for(auto to:v[t[i].id]){
s+=ask(to)+ask(to+m); if(s>=t[i].need) break;
}
if(s>=t[i].need) st[++tl]=t[i];
else st[++tr]=t[i],st[tr].need-=s;
}
for(int i=l;i<=mid;i++) insert(cl[i],-ca[i]),insert(cr[i]+1,ca[i]);
for(int i=1;i<=tl;i++) t[x+i-1]=st[i];
for(int i=n+1;i<=tr;i++) t[x+tl+i-n-1]=st[i];
solve(l,mid,x,x+tl-1),solve(mid+1,r,x+tl,y);
}
signed main(){
n=read(),m=read();
for(int i=1;i<=m;i++) v[read()].push_back(i);
for(int i=1;i<=n;i++) t[i].need=read(),t[i].id=i;
k=read();
for(int i=1;i<=k;i++) cl[i]=read(),cr[i]=read(),ca[i]=read();
for(int i=1;i<=k;i++) if(cr[i]<cl[i]) cr[i]+=m;
solve(1,k+1,1,n);
for(int i=1;i<=n;i++)
if(res[i]==k+1) puts("NIE");
else printf("%d\n",res[i]);
return 0;
}
青烟绕指柔!
发布了649 篇原创文章 · 获赞 242 · 访问量 4万+
私信
关注