【坑坑坑】数据结构 Contest

来源:互联网 发布:公司职位划分 知乎 编辑:程序博客网 时间:2024/06/05 16:23



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 longinline 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,Rvoid 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 secondtypedef 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]; // anspii 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 longinline 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 longinline 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;}



0 0