A
首先按s从小到大排序。
考虑枚举右端点r,往前扫l,用一个小根堆维护前m大。
一个显然的优化:当r被弹出堆时就可以停止扫描了,因为此时一定可以通过往左移动r来使得答案更优。
然后我们发现如果一个点i在r往左扫描时没有入堆,那么在r+1往左扫描时也不会入堆。因此可以直接删去。
用链表维护一下剩余可能入堆的点即可。
复杂度
O(nmlogm)
O
(
n
m
l
o
g
m
)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 200010
inline char gc(){
static char buf[1<<16],*S,*T;
if(T==S){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=gc();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
int n,m,ds,dv,pre[N];
ll ans=0;
struct Icefox{
int s,v;
friend bool operator<(Icefox a,Icefox b){return a.s<b.s;}
}a[N];
inline ll cal(ll x,int k){
return k==1?x:x*x;
}
int main(){
// freopen("ex_B3.in","r",stdin);
n=read();m=read();ds=read();dv=read();
for(int i=1;i<=n;++i) a[i].s=read(),a[i].v=read(),pre[i]=i-1;
sort(a+1,a+n+1);
for(int i=1;i<=n;++i){
priority_queue<int,vector<int>,greater<int> >q;
ll sum=0;int x=i,lst=i;
for(int j=1;j<=m;++j) q.push(0);
while(x){
int y=q.top();
if(y<a[x].v){
sum+=a[x].v-y;q.pop();q.push(a[x].v);
if(q.top()>a[i].v) break;
ans=max(ans,cal(sum,dv)-cal(a[i].s-a[x].s,ds));
}else pre[lst]=pre[x];
lst=x;x=pre[x];
}
}printf("%lld\n",ans);
return 0;
}
B
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100010
inline char gc(){
static char buf[1<<16],*S,*T;
if(T==S){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=gc();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
int n,m,fa[N],dis[N];
vector<int>Son[N],ans[N];
inline void dfs(int x){
for(int i=0;i<Son[x].size();++i){
int y=Son[x][i];dfs(y);dis[x]=max(dis[x],dis[y]+1);
}
}
struct Cmp{
bool operator()(int x,int y){
return dis[x]<dis[y];
}
};
int main(){
// freopen("ex_todotree3.in","r",stdin);
n=read();m=read();
for(int i=2;i<=n;++i) fa[i]=read(),Son[fa[i]].push_back(i);
dfs(1);priority_queue<int,vector<int>,Cmp>q;q.push(1);int cnt=0;
while(!q.empty()){
++cnt;
for(int i=1;i<=m;++i){
int x=q.top();q.pop();ans[cnt].push_back(x);if(q.empty()) break;
}for(int i=0;i<ans[cnt].size();++i){
int x=ans[cnt][i];
for(int j=0;j<Son[x].size();++j) q.push(Son[x][j]);
}
}printf("%d\n",cnt);
for(int i=1;i<=cnt;++i){
printf("%d ",(int)ans[i].size());
for(int j=0;j<ans[i].size();++j) printf("%d ",ans[i][j]);puts("");
}return 0;
}
C
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100010
#define mod 998244353
inline char gc(){
static char buf[1<<16],*S,*T;
if(T==S){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=gc();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
int n,m,h[N],num=0,rt[N],owo=0,ans=0;
struct edge{
int to,next,val;
}data[N<<1];
struct node{
int ls,rs,f[2][2],x;
inline int ans(){
ll res=(ll)(f[0][0]+1)*f[0][1]+(ll)f[1][0]*f[1][1];res%=mod;return res;
}
}tr[N*20];
vector<int>a[N];
inline void inc(int &x,int y){x+=y;if(x>=mod) x-=mod;}
inline node unit(int l,int r){
node res;res.x=0;res.f[0][1]=0;res.f[1][1]=0;
int half=r-l+1>>1;
res.f[1][0]=res.f[0][0]=half;
if((r-l+1)&1) res.f[l&1][0]++;return res;
}
inline void pushup(int p,int l,int mid,int r){
node ls=tr[p].ls?tr[tr[p].ls]:unit(l,mid),rs=tr[p].rs?tr[tr[p].rs]:unit(mid+1,r);
for(int i=0;i<2;++i)
for(int j=0;j<2;++j)
tr[p].f[i][j]=ls.f[i][j]+rs.f[i][j^ls.x];
tr[p].x=(ls.x+rs.x)&1;
}
inline void change(int &p,int l,int r,int x){
if(!p) p=++owo;if(l==r){tr[p].f[l&1][1]++;tr[p].x^=1;return;}
int mid=l+r>>1;
if(x<=mid) change(tr[p].ls,l,mid,x);
else change(tr[p].rs,mid+1,r,x);pushup(p,l,mid,r);
}
inline int merge(int p1,int p2,int l,int r){
if(!p1||!p2) return p1+p2;int mid=l+r>>1;
tr[p1].ls=merge(tr[p1].ls,tr[p2].ls,l,mid);
tr[p1].rs=merge(tr[p1].rs,tr[p2].rs,mid+1,r);pushup(p1,l,mid,r);return p1;
}
inline void dfs(int x,int Fa){
for(int i=0;i< a[x].size();++i) change(rt[x],1,m,a[x][i]);
for(int i=h[x];i;i=data[i].next){
int y=data[i].to;if(y==Fa) continue;
dfs(y,x);inc(ans,(ll)data[i].val*tr[rt[y]].ans()%mod);
rt[x]=merge(rt[x],rt[y],1,m);
}
}
int main(){
// freopen("ex_c3.in","r",stdin);
n=read();m=read();
for(int i=1;i< n;++i){
int x=read(),y=read(),val=read();
data[++num].to=y;data[num].next=h[x];h[x]=num;data[num].val=val;
data[++num].to=x;data[num].next=h[y];h[y]=num;data[num].val=val;
}for(int i=1;i<=m;++i) a[read()].push_back(i);dfs(1,0);
printf("%d\n",ans);
return 0;
}