CF1452E Two Editorials
这是一道反问题。
如果给你具体的两个author的区间,你就可以算出∑ai,现在是不告诉你author的区间,该如何选能使得总和最大。
许多出题人都喜欢出反问题,我感觉思考反问题也挺好玩的。
首先,这两个author应该是为了加强难度设置的,我们应该先考虑一个author的情况。
如果一个位置被x次区间覆盖,那么就设置数值为x,这样就等于找一个长度为k的区间使得区间和最大。
这很简单,先差分来对每个数字算出x,然后直接扫一遍。
现在有两个author,就涉及了max的问题。瞬间难度迷雾了起来。
看了题解,发现我只不过是没等到可以颠覆你一切思路的program的出现。
关键在于,对于一个区间[L,R],一个author区间,不断移动,可以发现当author区间的中点与区间[L,R]中点重合的时候,区间[L,R]被覆盖的长度是最大的。
因此,如果有两个author区间,区间中点离被覆盖区间中点的距离最近的那个才是发挥作用的区间。
因此,被覆盖的区间,被谁覆盖,是连续的分明的两段。
这就是二分所需要的单调性。
我们枚举这个分界点,然后在各自界内,独立地找出author的最优解,这部分可以预处理。
写了一半的代码:
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,n) for (int i=1;i<=n;i++)
#define REP(i,a,b) for (int i=a;i<=b;i++)
#define pb push_back
#define fi first
#define se second
#define pi pair<int,int>
#define mp make_pair
typedef long long ll;
typedef complex<double> comp;
const int inf=0x3f3f3f3f;
const ll linf=1e18;
const int N=5e5+10;
const double eps=1e-10;
const ll mo=1e9+7;
int n,m;
int k;
int l[N],r[N];
int a[N];
int f[N],g[N];
int ans;
struct node {
int l,r;
} b[N];
bool cmp(node x,node y) {
double xm=0.5*(x.l+x.r),ym=0.5*(y.l+y.r);
return xm<ym;
}
int main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
cin>>n>>m>>k;
FOR(i,m) {
cin>>l[i]>>r[i];
a[l[i]]++;
a[r[i]+1]--;
b[i].l=l[i],b[i].r=r[i];
}
sort(b+1,b+1+n,cmp);
FOR(i,n) l[i]=b[i].l,r[i]=b[i].r;
FOR(i,n) a[i]+=a[i-1];
REP(i,k,n) f[i]=max(f[i-1],a[i]-a[i-k]);
for (int i=n-k+1;i>=1;i--) g[i]=max(g[i+1],a[i+k-1]-a[i-1]);
int p=1;
REP(i,k+1,(n+n-k+1)) {
double j=0.5*i;
while (0.5*(l[p]+r[p])<=j) {
p++;
}
}
return 0;
}

浙公网安备 33010602011771号