P3527 [POI2011]MET-Meteors(整体二分)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3527 [POI2011]MET-Meteors(整体二分)相关的知识,希望对你有一定的参考价值。
P3527 [POI2011]MET-Meteors(整体二分)
考虑整体二分答案 k k k。
每次对于 [ l , m ] [l,m] [l,m]区间使用 B I T BIT BIT维护差分进行区间修改。
然后对于 [ q l , q r ] [ql,qr] [ql,qr]就单点查询然后求和,特判是否满足,若大于等于丢左子区间,否则丢右子区间,注意丢右子区间之后要减丢之前的贡献。
然后递归处理即可。
因为是环,所以考虑断环成链,将操作区间 l > r l>r l>r的修改成 [ l , r + m ] [l,r+m] [l,r+m],每次询问就加两个点。
为了方便处理 i n f inf inf情况,我们考虑再加一个修改区间 [ 1 , 2 m ] , a d d ( i n f ) [1,2m],add(inf) [1,2m],add(inf),然后答案是最后一个 k k k的就说明是无解。
// Problem: P3527 [POI2011]MET-Meteors
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3527
// Memory Limit: 64 MB
// Time Limit: 2500 ms
// Date: 2021-07-26 09:42:09
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=6e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
}
int n,m,k;
struct BIT{
#define lowbit(x) x&(-x)
#define il inline
ll s[N];
int n;
il void upd(int x,int v){
while(x<=2*m){
s[x]+=v;x+=lowbit(x);
}return;
}
il ll que(int x){
ll ans=0;
while(x){
ans+=s[x];x-=lowbit(x);
}return ans;
}
}T;
vector<int>a[N];
struct node{
int x,id;
}p[N],p1[N],p2[N];
struct query{
int l,r,x;
}q[N];
int ans[N];
void solve(int l,int r,int ql,int qr){
if(ql>qr) return;
if(l==r){
for(int i=ql;i<=qr;i++) ans[p[i].id]=l;return;
}
int mid=l+r>>1;
int c1=0,c2=0;
for(int i=l;i<=mid;i++) T.upd(q[i].l,q[i].x),T.upd(q[i].r+1,-q[i].x);
for(int i=ql;i<=qr;i++){
ll s=0;
int u=p[i].id;
for(int j:a[u]){
s+=T.que(j)+T.que(j+m);
if(s>=p[i].x) break;
}
if(s>=p[i].x) p1[++c1]=p[i];
else p[i].x-=s,p2[++c2]=p[i];
}
for(int i=1;i<=c1;i++) p[ql+i-1]=p1[i];
for(int i=1;i<=c2;i++) p[ql+i+c1-1]=p2[i];
for(int i=l;i<=mid;i++) T.upd(q[i].l,-q[i].x),T.upd(q[i].r+1,q[i].x);
solve(l,mid,ql,ql+c1-1),solve(mid+1,r,ql+c1,qr);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1,x;i<=m;i++)
scanf("%d",&x),a[x].pb(i);
for(int i=1;i<=n;i++) scanf("%d",&p[i].x),p[i].id=i;
scanf("%d",&k);
for(int i=1;i<=k;i++){
scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].x);
if(q[i].l>q[i].r) q[i].r+=m;
}
q[++k].l=1,q[k].r=2*m,q[k].x=inf;
solve(1,k,1,n);
for(int i=1;i<=n;i++)
if(ans[i]==k) puts("NIE");
else printf("%d\\n",ans[i]);
return 0;
}
以上是关于P3527 [POI2011]MET-Meteors(整体二分)的主要内容,如果未能解决你的问题,请参考以下文章