P3586 [POI2015]LOG

Portal

For inquiry, the first positive number if the number is less than $ c $ a is clearly no solution

Then if more than equal to the number of $ s $ $ c $ a greater than or equal, then obviously solvable

Otherwise, consider the greedy access, firstly an initial $ s $ greater than or equal to the number which can be taken every time we get to, the directly $ c-cnt $, $ where $ CNT is equal to greater than the initial number of $ s $ The number of

Then consider what the rest of the case is how to ensure that the final number of solvability

It found that as long as the rest of the sum is greater than the number seems to be equal to $ c * s $ will certainly solvable, prove consider this:

The number of the remaining split into a number of $ 1 and $ recombined, the final composition must be a value of $ c $ a $ s $ number

$ 1 $ consider each recording mark are marked with numbers which belong to the original, the original number of Save operations for each subsequent recombination $ $ -1, we can be regarded as the marking of the numerals 1 $ $

This will ultimately solvable, so the proof is completed

Then what you can segment tree maintenance

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
    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<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=2e6+7;
int n,m,a[N],d[N],inv[N];
int t[N<<2];
ll sum[N<<2];
inline void pushup(int o) { t[o]=t[o<<1]+t[o<<1|1]; sum[o]=sum[o<<1]+sum[o<<1|1]; }
void change(int o,int l,int r,int pos,int v)
{
    if(l==r) { t[o]+=v; sum[o]+=1ll*v*inv[l]; return; }
    int mid=l+r>>1;
    pos<=mid ? change(o<<1,l,mid,pos,v) : change(o<<1|1,mid+1,r,pos,v);
    pushup(o);
}
ll query2(int o,int l,int r,int qr)
{
    if(r<=qr) return sum[o];
    int mid=l+r>>1;
    if(mid<qr) return sum[o<<1]+query2(o<<1|1,mid+1,r,qr);
    return query2(o<<1,l,mid,qr);
}
int query3(int o,int l,int r,int pos)
{
    if(l==r) return t[o];
    int mid=l+r>>1;
    if(pos<=mid) return t[o<<1|1]+query3(o<<1,l,mid,pos);
    return query3(o<<1|1,mid+1,r,pos);
}
char s[N]; int da[N],db[N];
int main()
{
    n=read(),m=read();
    for(int i=1;i<=m;i++)
    {
        scanf("%s",&s[i]); da[i]=read(),db[i]=read();
        d[i]=db[i];
    }
    sort(d+1,d+m+1); int tot=unique(d+1,d+m+1)-d-1;
    for(int i=1;i<=m;i++)
    {
        int t=db[i]; db[i]=lower_bound(d+1,d+tot+1,db[i])-d;
        inv[db[i]]=t;
    }
    int cnt=0;
    for(int i=1;i<=m;i++)
    {
        if(s[i]=='U')
        {
            if(a[da[i]]) change(1,1,tot,a[da[i]],-1);
            else cnt++;
            a[da[i]]=db[i]; change(1,1,tot,db[i],1);
        }
        if(s[i]=='Z')
        {
            if(da[i]>cnt) { printf("NIE\n"); continue; }
            int t=da[i]-query3(1,1,tot,db[i]);
            if(t<=0) { printf("TAK\n"); continue; }
            if(1ll*t*inv[db[i]]<=query2(1,1,tot,db[i]-1)) printf("TAK\n");
            else printf("NIE\n");
        }
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/LLTYYC/p/11562905.html