求助入门分块
查看原帖
求助入门分块
294736
bovine__kebi楼主2020/6/8 20:23

RT,TLE道理我都懂,为啥WA了/kk

#pragma GCC optimize("Ofast","-funroll-loops","-fdelete-null-pointer-checks")
#pragma GCC target("ssse3","sse3","sse2","sse","avx2","avx")
#include<bits/stdc++.h>
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21], *p1 = buf, *p2 = buf;
typedef long long ll;
using namespace std;
const int maxn=1e5+5;
const ll Inf=1ll<<62;
inline ll read()
{
	ll x=0;int 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;
}
inline void print(ll x)
{
     if(x<0) putchar('-'),x=-x;
     if(x>9) print(x/10);
     putchar(x%10+'0');
}
ll a[maxn],tag[maxn];
int belong[maxn];
vector<ll>s[505];
int size;int n,m;
inline void reduce(int pos)
{
    s[pos].clear();
    for(register int i=(pos-1)*size+1;i<=min(pos*size,n);i++)s[pos].push_back(a[i]);
    sort(s[pos].begin(),s[pos].end());
}
inline void add(int l,int r,ll k)
{
    for(register int  i=l;i<=min(belong[l]*size,r);i++)a[i]+=k;
    reduce(belong[l]);
    if(belong[l]!=belong[r])
    {
        for(register int i=(belong[r]-1)*size+1;i<=r;i++)a[i]+=k;
        reduce(belong[r]);
    }
    for(register int i=belong[l]+1;i<=belong[r]-1;i++)tag[i]+=k;
}
inline bool _find(int l,int r,ll sum,int emm)
{
    int ans=0;
    for(register int i=l;i<=min(belong[l]*size,r);i++)if(a[i]+tag[belong[l]]<sum)ans++;
    if(belong[l]!=belong[r])
    {
        for(register int i=(belong[r]-1)*size+1;i<=r;i++)if(a[i]+tag[belong[r]]<sum)ans++;
    }
    for(register int i=belong[l]+1;i<=belong[r]-1;i++)
    {
        ll x=sum-tag[i];
        ans+=lower_bound(s[i].begin(),s[i].end(),x)-s[i].begin();
    }
    return ans<emm?true:false;
}
inline ll get(int l,int r,bool x)
{
    ll m=x?Inf:0;
    for(register int i=l;i<=min(belong[l]*size,r);i++)m=x?min(m,(ll)a[i]+tag[belong[l]]):max(m,(ll)a[i]+tag[belong[l]]);
    if(belong[l]!=belong[r])
    {
        for(register int i=(belong[r]-1)*size+1;i<=r;i++)m=x?min(m,(ll)a[i]+tag[belong[l]]):max(m,(ll)a[i]+tag[belong[l]]);
    }
    for(register int i=belong[l]+1;i<=belong[r]-1;i++)
    {
        m=x?min(m,(ll)s[i][0]+tag[i]):max(m,(ll)s[i][size-1]+tag[i]);
    }
    return m;
}
inline ll search(int l,int r,int k)
{
    if(r-l+1<k)return -1;
    ll m=get(l,r,1),n=get(l,r,0);
    while(m<n)
    {
        ll mid=((m+n)>>1)+1ll;
        if(_find(l,r,mid,k))m=mid;
        else n=mid-1;
    }
    return m;
}
int main()
{
    n=read();m=read();size=(int)sqrt(n)*log2(n);
    for(register int i=1;i<=n;i++)a[i]=read();
    for(register int i=1;i<=n;i++)belong[i]=(i-1)/size+1,s[belong[i]].push_back(a[i]);
    for(register int i=1;i<=belong[n];i++)sort(s[i].begin(),s[i].end());
    for(register int i=1;i<=m;i++)
    {
        int cz,l,r,k;
        cz=read();l=read();r=read();k=read();
        if(l>r)swap(l,r);
        if(cz==1)print(search(l,r,k)),putchar('\n');
        if(cz==2)add(l,r,k);
    }
}

我之前试着交了一篇blog,结果发现是可以过的。。我觉得我和他的写法也没差到哪里去啊/kel

2020/6/8 20:23
加载中...