B
矩形面积k次覆盖并
代码写得很不熟练
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define INE(i,u) for(int i=head[u];~i;i=e[i].next)
#define LL long long
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
const int N=30003;
int n,k;
struct Line{
int x,y1,y2,flag;
}l[N*2];
int y[N*2],tot,t;
int sum[N*8][12],cover[N*8];
bool cmp(const Line &A,const Line &B){return A.x<B.x;}
void up(int o,int L,int R)
{
rep(i,0,k) sum[o][i]=0;
/*if(cover[o]>=k)
{
sum[o][k]=y[R+1]-y[L];
}
else if(L!=R)
{
rep(i,cover[o],k-1) sum[o][i]=sum[o<<1][i-cover[o]]+sum[o<<1|1][i-cover[o]];
rep(i,k-cover[o],k) sum[o][k]+=sum[o<<1][i]+sum[o<<1|1][i];
}
else
{
sum[o][cover[o]]=y[R+1]-y[L];
}*/
rep(i,0,k)
{
if(cover[o]>=i)
{
sum[o][i]=y[R+1]-y[L];
}
else if(L!=R)
{
sum[o][i]=sum[o<<1][i-cover[o]]+sum[o<<1|1][i-cover[o]];
}
else
{
sum[o][i]=0;
}
}
}
#define LS o<<1,L,mid
#define RS o<<1|1,mid+1,R
void modify(int l,int r,int x,int o=1,int L=1,int R=t-1)
{
if(l<=L && R<=r)
{
cover[o]+=x;
up(o,L,R);
return;
}
int mid=L+R>>1;
if(r<=mid) modify(l,r,x,LS);
else if(l>mid) modify(l,r,x,RS);
else modify(l,mid,x,LS), modify(mid+1,r,x,RS);
up(o,L,R);
}
void input()
{
tot=0;
n=read(); k=read();
rep(i,1,n)
{
int x1=read(),y1=read(),x2=read(),y2=read(); x2++; y2++;
l[++tot].x=x1; l[tot].y1=y1; l[tot].y2=y2; l[tot].flag=1; y[tot]=y1;
l[++tot].x=x2; l[tot].y1=y1; l[tot].y2=y2; l[tot].flag=-1; y[tot]=y2;
}
sort(&l[1],&l[tot+1],cmp);
sort(&y[1],&y[tot+1]);
t=unique(&y[1],&y[tot+1])-&y[1];
}
void solve()
{
LL ans=0;
rep(i,1,tot)
{
int L=lower_bound(&y[1],&y[t+1],l[i].y1) - &y[1] + 1;
int R=lower_bound(&y[1],&y[t+1],l[i].y2) - &y[1] + 1;
if(i>1) ans+=(LL)(l[i].x-l[i-1].x)*sum[1][k];
modify(L,R-1,l[i].flag);
}
cout<<ans<<endl;
}
int main()
{
int t=read();
for(int T=1;T<=t;T++)printf("Case %d: ",T),
input(),solve();
return 0;
}
E
还不会分块的做法
H
很神的题啊
点分治+DP
代码实现得很麻烦,我写得最长
#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define INE(i,u) for(int i=head[u];~i;i=e[i].next)
#define LL long long
#define MP make_pair
#define X first
#define Y second
typedef pair<int,int>pii;
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
inline void MAX(int &a,int b){if(a<b)a=b;}
const int N=100010;
const int inf=0x3f3f3f3f;
int n;
struct edge{int v,w,next;}e[N*2];
int head[N],k;
bool sup[N];
int cnt[N],mx[N],size,rt;
bool flag[N];
int dp[N]; // ans
pii mi[N],cur;
vector<pii>S; // c#!¥f%@#...¥$%¥2&... 据说vector自带分块
void adde(int u,int v,int w)
{
e[k].v=v;
e[k].w=w;
e[k].next=head[u];
head[u]=k++;
}
void getroot(int u,int fa)
{
cnt[u]=1; mx[u]=0;
INE(i,u)
{
int v=e[i].v; if(v==fa || flag[v]) continue;
getroot(v,u);
cnt[u]+=cnt[v];
MAX(mx[u],cnt[v]);
}
MAX(mx[u],size-cnt[u]);
if(mx[u] < mx[rt]) rt=u;
}
void addans(int u,int fa,int dis)
{
if(sup[u]) cur=min(cur,MP(dis,u));
else INE(i,u) // !
{
int v=e[i].v; if(v==fa || flag[v]) continue;
addans(v,u,dis+e[i].w);
}
}
void add(int u,int fa,int dis)
{
if(!sup[u]) mi[u]=min(mi[u],MP(cur.X+dis,cur.Y));
INE(i,u)
{
int v=e[i].v; if(v==fa || flag[v]) continue;
add(v,u,dis+e[i].w);
}
}
void cal1(int u) // 并不知道怎么写,那就暴力的写吧QwQ 好丑陋
{
static vector<pii>son; rep(i,0,son.size()-1) son.pop_back();
INE(i,u)
{
int v=e[i].v; if(flag[v]) continue;
son.push_back(MP(v,e[i].w));
}
if(sup[u]) cur=MP(0,u);
else cur=MP(inf,inf);
rep(i,0,son.size()-1)
{
int v=son[i].X,w=son[i].Y;
addans(v,u,w);
add(v,u,w);
}
if(!sup[u]) mi[u]=min(mi[u],cur);
if(sup[u]) cur=MP(0,u);
else cur=MP(inf,inf);
per(i,son.size()-1,0)
{
int v=son[i].X,w=son[i].Y;
addans(v,u,w);
add(v,u,w);
}
if(!sup[u]) mi[u]=min(mi[u],cur);
}
void divide(int u)
{
flag[u]=1;
cal1(u);
INE(i,u)
{
int v=e[i].v; if(flag[v]) continue;
size=mx[rt=0]=cnt[v];
getroot(v,u);
divide(rt);
}
}
void insert(pii x)
{
S.insert(lower_bound(S.begin(),S.end(),x),x);
}
int getrank(int dis,int u)
{
return S.end()-lower_bound(S.begin(),S.end(),MP(dis,u));
}
void addans2(int u,int fa,int dis)
{
if(!sup[u]) dp[u]+=getrank(dis,u);
INE(i,u)
{
int v=e[i].v; if(v==fa || flag[v]) continue;
addans2(v,u,dis+e[i].w);
}
}
void add2(int u,int fa,int dis)
{
if(!sup[u]) if(mi[u].X-dis>=0) insert(MP(mi[u].X-dis,mi[u].Y));
INE(i,u)
{
int v=e[i].v; if(v==fa || flag[v]) continue;
add2(v,u,dis+e[i].w);
}
}
void cal2(int u) // 还是不知道怎么写
{
static vector<pii>son; rep(i,0,son.size()-1) son.pop_back();
INE(i,u)
{
int v=e[i].v; if(flag[v]) continue;
son.push_back(MP(v,e[i].w));
}
S.clear();
if(!sup[u]) insert(MP(mi[u].X,mi[u].Y));
rep(i,0,son.size()-1)
{
int v=son[i].X,w=son[i].Y;
addans2(v,u,w);
add2(v,u,w);
}
if(!sup[u]) dp[u]+=getrank(0,u);
S.clear();
per(i,son.size()-1,0)
{
int v=son[i].X,w=son[i].Y;
addans2(v,u,w);
add2(v,u,w);
}
}
void divide2(int u)
{
flag[u]=1;
cal2(u);
INE(i,u)
{
int v=e[i].v; if(flag[v]) continue;
size=mx[rt=0]=cnt[v];
getroot(v,u);
divide2(rt);
}
}
void input()
{
rep(i,1,n) head[i]=-1,flag[i]=0,dp[i]=0,mi[i]=MP(inf,inf); k=0;
rep(i,2,n)
{
int u=read(),v=read(),w=read();
adde(u,v,w); adde(v,u,w);
}
rep(i,1,n) sup[i]=read();
}
void solve()
{
size=mx[rt=0]=n;
getroot(1,0);
divide(rt);
MS(flag,0);
size=mx[rt=0]=n;
getroot(1,0);
divide2(rt);
int ans=0;
rep(i,1,n) if(!sup[i]) MAX(ans,dp[i]);
printf("%d\n",ans);
//rep(i,1,n) printf("%d\n",mi[i].Y);
}
int main()
{
while(~scanf("%d",&n))
input(),solve();
return 0;
}
I
动态树分治先放着
J
不会
K
整体二分
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define INE(i,u) for(int i=head[u];~i;i=e[i].next)
#define LL long long
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
void MAX(int &a,int b){if(a<b)a=b;}
void MIN(int &a,int b){if(a>b)a=b;}
const int inf=0x3f3f3f3f;
const int N=50005;
const int Q=10010;
int n,m;
int a[N],mi,mx;
struct data{int x,y,z,op,id,cur,delta;}q[N+Q*2];
int tot;
int ans[Q];
int mid;
int c[N];
void add(int o,int x){for(;o<=n;o+=o&-o)c[o]+=x;}
int query(int o){int s=0;for(;o;o-=o&-o)s+=c[o];return s;}
bool part(data &x)
{
if(x.op==3)
{
if(x.cur+x.delta>=x.z) return 1;
x.cur+=x.delta; x.delta=0;
return 0;
}
return x.y<=mid;
}
void cal(int l,int r,int L,int R)
{
if(L==R)
{
rep(i,l,r) if(q[i].op==3) ans[q[i].id]=L;
return;
}
mid=L+R>>1;
rep(i,l,r)
{
if(q[i].op==1 && q[i].y<=mid) add(q[i].x,1);
if(q[i].op==2 && q[i].y<=mid) add(q[i].x,-1);
if(q[i].op==3) q[i].delta=query(q[i].y)-query(q[i].x-1);
}
rep(i,l,r)
{
if(q[i].op==1 && q[i].y<=mid) add(q[i].x,-1);
if(q[i].op==2 && q[i].y<=mid) add(q[i].x,1);
}
int div=stable_partition(&q[l],&q[r+1],part)-&q[1];
if(l<=div) cal(l,div,L,mid);
if(div+1<=r) cal(div+1,r,mid+1,R);
}
void input()
{
mi=inf; mx=-inf; tot=0; *ans=0;
n=read(); m=read();
rep(i,1,n)
{
a[i]=read(); MAX(mx,a[i]); MIN(mi,a[i]);
q[++tot]=(data){i,a[i],0,1,0,0};
}
rep(i,1,m)
{
char op[3]; scanf("%s",op);
if(op[0] == 'C')
{
int pos=read(),x=read();
q[++tot]=(data){pos,a[pos],0,2,0,0,0};
a[pos]=x; MAX(mx,x); MIN(mi,x);
q[++tot]=(data){pos,a[pos],0,1,0,0,0};
}
else
{
int l=read(),r=read(),k=read();
q[++tot]=(data){l,r,k,3,++*ans,0,0};
}
}
}
void solve()
{
cal(1,tot,mi,mx);
rep(i,1,*ans) printf("%d\n",ans[i]);
}
int main()
{
rep(i,1,read())
input(),solve();
return 0;
}
M
还是我写得最长QwQ
N
转化为矩形面积并,怎么反应慢了
O
可持久化线段树,不太会
P
树上的主席树
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define INE(i,u) for(int i=head[u];~i;i=e[i].next)
#define LL long long
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
const int N=100010;
int n,m;
int w[N],t[N],tot;
struct edge{int v,next;}e[N*2];
int head[N],k;
int in[N],_in[N],ind;
int fa[N][17],dep[N];
int root[N],sz;
int ls[N*20],rs[N*20],sum[N*20];
void adde(int u,int v){e[k]=(edge){v,head[u]};head[u]=k++;}
int find(int x)
{
int l=1,r=tot,mid;
while(l<r)
{
mid=l+r+1>>1;
if(x<t[mid]) r=mid-1;
else l=mid;
}
return l;
}
void dfs(int u)
{
in[u]=++ind; _in[in[u]]=u;
INE(i,u)
{
int v=e[i].v; if(v==fa[u][0]) continue;
fa[v][0]=u; rep(i,1,16) fa[v][i]=fa[fa[v][i-1]][i-1];
dep[v]=dep[u]+1;
dfs(v);
}
}
int lca(int a,int b)
{
if(dep[a]<dep[b]) swap(a,b);
int d=dep[a]-dep[b];
rep(i,0,16) if(d>>i&1) a=fa[a][i];
if(a==b) return a;
per(i,16,0) if(fa[a][i]^fa[b][i]) a=fa[a][i],b=fa[b][i];
return fa[a][0];
}
void update(int &o,int lst,int x,int L,int R)
{
o=++sz; sum[o]=sum[lst]+1; ls[o]=ls[lst]; rs[o]=rs[lst];
if(L==R) return;
int mid=L+R>>1;
if(x<=mid) update(ls[o],ls[lst],x,L,mid);
else update(rs[o],rs[lst],x,mid+1,R);
}
int getans(int x,int y,int k)
{
int anc=lca(x,y),f=fa[anc][0];
int a=root[in[x]],b=root[in[y]],c=root[in[anc]],d=root[in[f]];
int l=1,r=tot;
while(l<r)
{
int mid=l+r>>1;
int cnt=sum[ls[a]]+sum[ls[b]]-sum[ls[c]]-sum[ls[d]];
if(cnt>=k) a=ls[a],b=ls[b],c=ls[c],d=ls[d],r=mid;
else a=rs[a],b=rs[b],c=rs[c],d=rs[d],l=mid+1,k-=cnt;
}
return t[l];
}
void input()
{
MS(head,-1);
n=read(); m=read();
rep(i,1,n) t[i]=w[i]=read();
sort(&t[1],&t[n+1]);
tot=unique(&t[1],&t[n+1])-t-1;
rep(i,1,n) w[i]=find(w[i]);
rep(i,2,n)
{
int u=read(),v=read();
adde(u,v); adde(v,u);
}
}
void solve()
{
dfs(1);
rep(i,1,n)
{
int u=_in[i];
update(root[i],root[in[fa[u][0]]],w[u],1,tot);
}
while(m--)
{
int u=read(),v=read(),k=read();
printf("%d\n",getans(u,v,k));
}
}
int main()
{
input(),solve();
return 0;
}
U
LCT
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define INE(i,u) for(int i=head[u];~i;i=e[i].next)
#define LL long long
#define LS c[0]
#define RS c[1]
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
void MIN(int &a,int b){if(a>b)a=b;}
void MAX(int &a,int b){if(a<b)a=b;}
const int inf=0x3f3f3f3f;
const int N=50005;
int n;
struct node *null;
struct node{
node *c[2],*fa;
bool d(){return this==fa->RS;}
void setc(node *ch,bool d){ch->fa=this;c[d]=ch;}
bool isroot(){return this!=fa->LS && this!=fa->RS;}
bool rev;
int w;
int slr,srl;
int mil,mir,mi;
int mxl,mxr,mx;
int add;
void Setv(int x)
{
w=mil=mir=mxl=mxr=mi=mx=x;
}
void Add(int x)
{
if(this==null) return;
w+=x; add+=x;
mil+=x; mir+=x; mi+=x;
mxl+=x; mxr+=x; mx+=x;
}
void Flip()
{
if(this==null) return;
rev^=1; swap(LS,RS);
swap(slr,srl);
}
void down()
{
if(add)
{
LS->Add(add);
RS->Add(add);
add=0;
}
if(rev)
{
LS->Flip();
RS->Flip();
rev=0;
}
}
void up()
{
mil=mir=mxl=mxr=mi=mx=w;
slr=srl=0;
if(LS!=null)
{
MIN(mil,LS->mi);
MAX(mxl,LS->mx);
MAX(slr,LS->slr);
MAX(srl,LS->srl);
}
if(RS!=null)
{
MIN(mir,RS->mi);
MAX(mxr,RS->mx);
MAX(slr,RS->slr);
MAX(srl,RS->srl);
}
mi=min(mil,mir);
mx=max(mxl,mxr);
MAX(slr,mxr-mil);
MAX(srl,mxl-mir);
}
void init()
{
LS=RS=fa=null;
rev=0;
w=0;
slr=srl=0;
mi=mil=mir=inf;
mx=mxl=mxr=-inf;
add=0;
}
}T[N];
void rot(node *o)
{
node *f=o->fa;
f->down(); o->down();
bool d=o->d();
if(!f->isroot()) f->fa->setc(o,f->d());
else o->fa=f->fa;
f->setc(o->c[!d],d); o->setc(f,!d);
f->up();
}
void splay(node *o)
{
for(o->down();!o->isroot();rot(o));
o->up();
}
void access(node *o)
{
for(node *t=null;o!=null;t=o,o=o->fa)
splay(o),o->RS=t;
}
void makeroot(node *o)
{
access(o); splay(o); o->Flip();
}
void split(node *x,node *y)
{
makeroot(x); access(y); splay(y);
}
void link(node *x,node *y)
{
makeroot(x); x->fa=y;
}
void input()
{
n=read();
null=&T[0]; null->init();
rep(i,1,n)
{
T[i].init();
T[i].Setv(read());
}
rep(i,2,n)
{
int u=read(),v=read();
link(&T[u],&T[v]);
}
}
void solve()
{
rep(__,1,read())
{
int u=read(),v=read(),x=read();
split(&T[u],&T[v]);
printf("%d\n",T[v].slr);
T[v].Add(x);
}
}
int main()
{
rep(i,1,read())
input(),solve();
return 0;
}