其他分享
首页 > 其他分享> > MET-Meteors

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;
}
青烟绕指柔! 发布了649 篇原创文章 · 获赞 242 · 访问量 4万+ 私信 关注

标签:二分,ch,Meteors,int,tr,long,MET,need
来源: https://blog.csdn.net/weixin_43826249/article/details/104554700