MET-Meteors

題目鏈接: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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章