[POI2011]MET-Meteors

Given a ring, each node has a country to which it belongs, k events, each time a value is added to the weight of each point on the [l,r] interval, and the earliest number of operations in each country is obtained. Right and can reach a value
https://www.luogu.org/problemnew/show/P3527

Calculate the number of each country that has been collected at mid time each time, put all the countries that can be completed on the left, and all the countries that cannot be completed are placed on the right. Continue to the left for two minutes or less and the right to continue for two minutes or more.
To judge whether it can be completed, use the tree-like array to violently update it.

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
typedef long long LL;
LL c[300005];
vector<int> G[300005];
int L[300005],R[300005],val[300005];
int P[300005],ans[300005];
int q[300005],q1[300005],q2[300005];
int n,m,k,now=0;
inline int read() {
    int sum=0;char ch=0;
    while (ch>'9' || ch<'0') ch=getchar();
    while (ch>='0' && ch<='9') sum=sum*10+ch-'0',ch=getchar();
    return sum;
}
inline int lowbit(int x) {
    return x&-x;
}
inline void add(int x,int v) {
    for (;x<=m;x+=lowbit(x)) c[x]+=v;
}
inline LL query(int x) {
    LL tmp=0;
    for (;x>0;x-=lowbit(x)) tmp+=c[x];
    return tmp;
}
inline void update(int l,int r,int v) {
    if (l<=r) {
        add(l,v);add(r+1,-v);
    }
    else {
        add(1,v);add(r+1,-v);
        add(l,v);add(m+1,-v);
    }
}
void bs(int l,int r,int s,int t) {//lr二分k st代表国家位置 
    if (s>t) return;
    if (l==r) {
        for (int i=s;i<=t;i++) ans[q[i]]=l;
        return;
    }
    int mid=(l+r)>>1;
    while (now<mid) now++,update(L[now],R[now],val[now]);
    while (now>mid) update(L[now],R[now],-val[now]),now--;
    int s1=0,s2=0;
    for (int i=s;i<=t;i++) {
        LL tmp=0;
        int x=q[i];
        for (int j=0;j<G[x].size();j++) {
            tmp+=query(G[x][j]);
            if (tmp>=P[x]) break;
        }
        if (tmp>=P[x]) q1[++s1]=x;
        else q2[++s2]=x;
    }
    for (int i=1;i<=s1;i++) q[s+i-1]=q1[i];
    for (int i=1;i<=s2;i++) q[s+s1+i-1]=q2[i];
    bs(l,mid,s,s+s1-1);
    bs(mid+1,r,s+s1,t);
}
int main() {
    n=read();m=read();
    for (int i=1;i<=m;i++) G[read()].push_back(i);
    for (int i=1;i<=n;i++) {
        P[i]=read();
        q[i]=i;
    }
    k=read();
    for (int i=1;i<=k;i++) {
        L[i]=read();R[i]=read();val[i]=read();
    }
    bs(1,k+1,1,n);
    for (int i=1;i<=n;i++) {
        if (ans[i]==k+1) printf("NIE\n");
        else printf("%d\n",ans[i]);
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324621945&siteId=291194637