zoukankan      html  css  js  c++  java
  • 【SPOJ METEORS】 Meteors

    http://www.spoj.com/problems/METEORS/ (题目链接)

    题意

      一个星球上有$m$个空间站排列在一个环形轨道上,每个空间站仅属于一个国家。总共有$K$场流星雨,这些流星雨降落在区间$[l,r]$的空间站并带来$w$的陨石。每个国家想要收获$p_i$的陨石,问每个国家最少在第几场流星雨过后收集到的陨石达到要求。

    Solution

      整体二分很明显,一开始复杂度算错了T_T。

    细节

      本机7s,SPOJ竟然跑过去了w(゚Д゚)w。听说会爆LL

    代码

    // spojMETEORS
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define ULL unsigned long long
    #define inf 2147483600
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
    using namespace std;
    inline int gi() {
    	int x=0,f=1;char ch=getchar();
    	while (ch<'0' || ch>'9') {if (ch=='-') f=-1;ch=getchar();}
    	while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    
    const int maxn=300010;
    int n,m,K,cnt,a[maxn],ans[maxn],head[maxn];
    struct edge {int to,next;}e[maxn];
    struct data {int w,id;}p[maxn],lp[maxn],rp[maxn];
    struct node {int l,r;ULL s,tag;}tr[maxn<<2];
    struct mete {int l,r,w;}q[maxn];
    
    namespace Segtree {
    	void build(int k,int s,int t) {
    		tr[k].l=s;tr[k].r=t;
    		if (s==t) return;
    		int mid=(s+t)>>1;
    		build(k<<1,s,mid);
    		build(k<<1|1,mid+1,t);
    	}
    	void modify(int k,int s,int t,LL val) {
    		int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
    		if (l==s && r==t) {tr[k].s+=val*(r-l+1);tr[k].tag+=val;return;}
    		if (t<=mid) modify(k<<1,s,t,val);
    		else if (s>mid) modify(k<<1|1,s,t,val);
    		else modify(k<<1,s,mid,val),modify(k<<1|1,mid+1,t,val);
    		tr[k].s=tr[k<<1].s+tr[k<<1|1].s;
    	}
    	ULL query(int k,int p) {
    		int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
    		if (l==r) return tr[k].s;
    		if (p<=mid) return query(k<<1,p)+tr[k].tag;
    		else return query(k<<1|1,p)+tr[k].tag;
    	}
    }
    using namespace Segtree;
    
    void link(int u,int v) {
    	e[++cnt]=(edge){v,head[u]};head[u]=cnt;
    }
    void solve(int ql,int qr,int l,int r) {
    	if (ql>qr) return;
    	int mid=(ql+qr)>>1,l1=0,l2=0;
    	for (int i=ql;i<=mid;i++) {
    		if (q[i].l>q[i].r) modify(1,q[i].l,m,q[i].w),modify(1,1,q[i].r,q[i].w);
    		else modify(1,q[i].l,q[i].r,q[i].w);
    	}
    	for (int i=l;i<=r;i++) {
    		ULL sum=0;
    		for (int j=head[p[i].id];j;j=e[j].next) sum+=query(1,e[j].to);
    		if (p[i].w<=sum) lp[++l1]=p[i],ans[p[i].id]=mid;
    		else rp[++l2]=p[i];
    	}
    	for (int i=1;i<=l1;i++) p[l+i-1]=lp[i];
    	for (int i=1;i<=l2;i++) p[r-i+1]=rp[i];
    	if (l+l1<=r) solve(mid+1,qr,l+l1,r);
    	for (int i=ql;i<=mid;i++) {
    		if (q[i].l>q[i].r) modify(1,q[i].l,m,-q[i].w),modify(1,1,q[i].r,-q[i].w);
    		else modify(1,q[i].l,q[i].r,-q[i].w);
    	}
    	if (l<=r-l2) solve(ql,mid-1,l,r-l2);
    }
    int main() {
    	n=gi(),m=gi();
    	for (int i=1;i<=m;i++) a[i]=gi();
    	for (int i=1;i<=m;i++) link(a[i],i);
    	for (int i=1;i<=n;i++) p[i].w=gi(),p[i].id=i;
    	K=gi();
    	for (int i=1;i<=K;i++) q[i].l=gi(),q[i].r=gi(),q[i].w=gi();
    	build(1,1,m);
    	solve(1,K,1,n);
    	for (int i=1;i<=n;i++) {
    		if (!ans[i]) puts("NIE");
    		else printf("%d
    ",ans[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Android带头像的用户注册页面
    Android——四种AterDialog
    Android Studio如何显示行号
    月下载量上千次的APP源码分享
    Android——列表视图(ListView)
    Android——列表选择框(Spinner)
    Android——按钮的事件监听
    ACM——第几天
    Android——控制UI界面
    Android——将图片加入到系统相册里面
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/6522756.html
Copyright © 2011-2022 走看看