最小表示法(poj1509)
#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; #define ll long long const int maxn=1e5+7; int T,n; char s[maxn]; char cc;ll ff; template<typename T>void read(T& aa) { aa=0;ff=1; cc=getchar(); while(cc!='-'&&(cc<'0'||cc>'9')) cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff; } int solve() { int i=0,j=1,k=0,t; while(i<n&&j<n&&k<n) { t=s[(i+k)%n]-s[(j+k)%n]; if(t==0) k++; else { if(t>0) i+=k+1; else j+=k+1; if(i==j) j++; k=0; } } return min(i,j); } int main() { read(T); while(T--) { scanf("%s",s); n=strlen(s); printf("%d ",solve()+1); } return 0; }
sg函数(hdu1848)
#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; #define ll long long const int maxn=1000+7; int n[3],f[maxn],sg[maxn],ans; char cc;ll ff; template<typename T>void read(T& aa) { aa=0;ff=1; cc=getchar(); while(cc!='-'&&(cc<'0'||cc>'9')) cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff; } bool vis[maxn]; int get_sg(int x) { memset(vis,0,sizeof(vis)); for(int i=1;f[i]<=x;++i) vis[sg[x-f[i]]]=1; for(int i=0;;++i) if(!vis[i]) return i; } int main() { f[0]=f[1]=1; for(int i=2;i<=1000;++i) { f[i]=f[i-1]+f[i-2]; if(f[i]>1000) break; } memset(sg,-1,sizeof(sg));sg[0]=0; for(int i=1;i<=1000;++i) sg[i]=get_sg(i); read(n[0]); read(n[1]); read(n[2]); while(n[0]||n[1]||n[2]) { ans=sg[n[0]]^sg[n[1]]^sg[n[2]]; if(ans) printf("Fibo "); else printf("Nacci "); read(n[0]); read(n[1]); read(n[2]); } return 0; }
树hash(bzoj4337)
#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; #define ll long long const int maxn=50+7; const ll base=1031,bs=1234,bse=5107043,mod=1000000007; int n,m,fa[maxn],ans; char cc;ll ff; template<typename T>void read(T& aa) { aa=0;ff=1; cc=getchar(); while(cc!='-'&&(cc<'0'||cc>'9')) cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff; } int fir[maxn],nxt[2*maxn],to[2*maxn],e=0; void add(int x,int y) { to[++e]=y; nxt[e]=fir[x]; fir[x]=e; to[++e]=x; nxt[e]=fir[y]; fir[y]=e; } ll hsh[maxn],now[maxn],zz[maxn],t,fz[maxn],tt; bool vis[maxn]; void get_hash(int pos) { vis[pos]=1; for(int y=fir[pos];y;y=nxt[y]) if(!vis[to[y]]) get_hash(to[y]); t=0; for(int y=fir[pos];y;y=nxt[y]) if(!vis[to[y]]) zz[++t]=now[to[y]]; vis[pos]=0; if(!t) { now[pos]=bs; return; } sort(zz+1,zz+t+1); for(int i=1;i<=t;++i) { now[pos]^=zz[i]; now[pos]=now[pos]*base%mod; } } int main() { read(m); for(int i=1;i<=m;++i) { read(n); memset(fir,0,sizeof(fir)); e=0; tt=0; for(int j=1;j<=n;++j) { read(fa[j]); if(fa[j]) add(fa[j],j); } for(int j=1;j<=n;++j) { memset(now,0,sizeof(now)); memset(vis,0,sizeof(vis)); get_hash(j); fz[j]=now[j]; } sort(fz+1,fz+n+1); for(int j=1;j<=n;++j) hsh[i]=(hsh[i]^fz[j])*bse%mod; for(int j=i;j;--j) if(hsh[j]==hsh[i]) ans=j; printf("%d ",ans); } return 0; } /* 4 4 0 1 1 2 4 2 0 2 3 4 0 1 1 1 4 0 1 2 3 */
笛卡尔树(poj1785)
#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; #define ll long long const int maxn=50000+7; int n,p[maxn],pr[maxn]; char c,s[maxn][117]; char cc;ll ff; template<typename T>void read(T& aa) { aa=0;ff=1; cc=getchar(); while(cc!='-'&&(cc<'0'||cc>'9')) cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff; } int ui; bool cmp(int x,int y) { return strcmp(s[x],s[y])<=0; } int son[maxn][2],root; int zz[maxn],t,last; void print_ans(int pos) { printf("("); if(son[pos][0]) print_ans(son[pos][0]); printf("%s/%d",s[pos],pr[pos]); if(son[pos][1]) print_ans(son[pos][1]); printf(")"); } void solve() { t=0; memset(son,0,sizeof(son)); root=0; for(int i=1;i<=n;++i) { last=0; while(t&&pr[zz[t]]<pr[p[i]]) { last=zz[t]; t--; } son[p[i]][0]=last; if(!t) root=p[i]; else son[zz[t]][1]=p[i]; zz[++t]=p[i]; } print_ans(root); } int main() { scanf("%d",&n); while(n) { for(int i=1;i<=n;++i) { p[i]=i; scanf("%*[ ]%[^/]/%d",s[i],&pr[i]); } sort(p+1,p+n+1,cmp); solve();printf(" "); scanf("%d",&n); } return 0; } /* 7 a/7 b/6 c/5 d/4 e/3 f/2 g/1 7 a/1 b/2 c/3 d/4 e/5 f/6 g/7 7 a/3 b/6 c/4 d/7 e/2 f/5 g/1 0 */
StoerWagner(poj2914)
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; #define ll long long #define For(i,a,b) for(int i=(a);i<=(b);++i) #define Rep(i,a,b) for(int i=(a);i>=(b);--i) const int maxn=500+7,maxm=maxn*maxn*2; const ll INF=1e14; int n,m; char cc; ll ff; template<typename T>void read(T& aa) { aa=0;cc=getchar();ff=1; while((cc<'0'||cc>'9')&&cc!='-') cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff; } ll v[maxn],wage[maxn],num[maxn][maxn]; bool vis[maxn]; ll StoerWagner() { ll rs=INF; int last,now=1; For(i,1,n) v[i]=i; Rep(nn,n,2) { memset(vis,0,sizeof(vis)); memset(wage,0,sizeof(wage)); now=1; For(i,1,nn-1) { vis[now]=1; last=now; now=0; For(j,1,nn) if(!vis[j]) { wage[j]+=num[v[last]][v[j]]; if(now==0||wage[j]>wage[now]) now=j; } } rs=min(rs,wage[now]); For(i,1,nn) { num[v[i]][v[last]]+=num[v[now]][v[i]]; num[v[last]][v[i]]+=num[v[now]][v[i]]; } v[now]=v[nn]; } return rs; } int main() { int x,y,z; while(scanf("%d%d",&n,&m)==2) { memset(num,0,sizeof(num)); For(i,1,m) { read(x); read(y); read(z); ++x; ++y; num[x][y]+=z; num[y][x]+=z; } printf("%lld ",StoerWagner()); } return 0; }
最小割树(bzoj2229)
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<queue> using namespace std; #define ll long long const int maxn=150+7,maxm=6000+7; const ll INF=1e14; int Td,n,m,q,S,T,tot; ll pp[maxn*maxn],ans[maxn][maxn]; char cc; ll ff; template<typename T>void read(T& aa) { aa=0;cc=getchar();ff=1; while((cc<'0'||cc>'9')&&cc!='-') cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff; } int a[maxn]; struct Node{ int x,y;ll flow,cap; Node(){} Node(int x,int y,ll cap):x(x),y(y),cap(cap){flow=0;} }node[2*maxm]; int cur[maxn],fir[maxn],nxt[2*maxm],e=1; void add(int x,int y,ll z) { // printf("add: %d->%d %lld ",x,y,z); node[++e]=Node(x,y,z); nxt[e]=fir[x];fir[x]=e; node[++e]=Node(y,x,0); nxt[e]=fir[y];fir[y]=e; } int dis[maxn],zz[maxn]; bool bfs() { int x,y,z,s=1,t=0; memset(dis,-1,sizeof(dis)); zz[++t]=S; dis[S]=0; while(s<=t) { x=zz[s++]; if(x==T) return 1; for(y=fir[x];y;y=nxt[y]) { if(dis[z=node[y].y]!=-1||node[y].flow>=node[y].cap) continue; dis[z]=dis[x]+1; zz[++t]=z; } } return 0; } ll dfs(int pos,ll maxf) { if(pos==T||maxf==0) return maxf; ll now,rs=0,z; for(int &y=cur[pos];y&&maxf;y=nxt[y]) { if(dis[z=node[y].y]!=dis[pos]+1||node[y].flow>=node[y].cap) continue; now=dfs(z,min(maxf,node[y].cap-node[y].flow)); node[y].flow+=now; node[y^1].flow-=now; maxf-=now; rs+=now; } if(!rs) dis[pos]=-1; return rs; } ll Dinic() { ll rs=0; while(bfs()) { memcpy(cur,fir,sizeof(fir)); rs+=dfs(S,INF); } return rs; } bool vis[maxn]; void dfs2(int pos) { if(vis[pos]) return;// vis[pos]=1; int y,z; for(y=fir[pos];y;y=nxt[y]) { if(node[y].flow>=node[y].cap) continue; z=node[y].y; dfs2(z); } } void solve(int l,int r) { if(l==r) return; for(int i=2;i<=e;++i) node[i].flow=0; S=a[l]; T=a[r]; ll x=Dinic(); memset(vis,0,sizeof(vis)); dfs2(S); for(int i=1;i<=n;++i) if(vis[i]) for(int j=1;j<=n;++j) if(!vis[j]) ans[i][j]=ans[j][i]=min(ans[i][j],x); for(int i=l;i<=r;++i) zz[i]=a[i]; int s=l-1,t=r+1; for(int i=l;i<=r;++i) { if(vis[zz[i]]) a[++s]=zz[i]; else a[--t]=zz[i]; } solve(l,s); solve(t,r); } void clear() { for(int i=1;i<=n;++i) a[i]=i; e=1; memset(fir,0,sizeof(fir)); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) ans[i][j]=INF; } int ef(ll x) { int l=0,r=tot+1,mid; pp[r]=INF; while(l<r-1) { mid=(l+r)>>1; if(pp[mid]<=x) l=mid; else r=mid; } return l; } int main() { read(Td); int x,y,z; while(Td--) { read(n); read(m); clear(); for(int i=1;i<=m;++i) { read(x); read(y); read(z); add(x,y,z); add(y,x,z); } solve(1,n); tot=0; for(int i=1;i<n;++i) for(int j=i+1;j<=n;++j) pp[++tot]=ans[i][j]; sort(pp+1,pp+tot+1); read(q); for(int i=1;i<=q;++i) { read(x); printf("%d ",ef(x)); } printf(" "); } return 0; } /* 2 5 0 1 0 5 0 1 0 */
平面曼哈顿距离最小生成树
对于每个点,以它为中心把平面平均分成八个,每个面里面找一个距离它最近的点连一条边,然后做最小生成树即可。
原因:由最小生成树环切性质,如果形成一个环,最长的那条边是没有用的
如图,在东偏北区域内,|AB|<=|AC|,那么肯定有|AC|>=|BC|
所以AC是不优的。
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; #define ll long long #define db double #define For(i,a,b) for(int i=(a);i<=(b);++i) #define Rep(i,a,b) for(int i=(a);i>=(b);--i) const int maxn=1e6+7,maxt=19,W=18; const db INF=1e9; int n,m,nowop=0;ll sumtot; ll px[maxn],py[maxn],p[maxn]; char cc; ll ff; template<typename T>void read(T& aa) { aa=0;cc=getchar();ff=1; while((cc<'0'||cc>'9')&&cc!='-') cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff; } db pf(const db x){return x*x;} const db eps=1e-12,PI=acos(-1),qr2=sqrt(2); int dcmp(db x){return fabs(x)<eps? 0:(x>0? 1:-1);} struct Node{ int id; db x,y; }node[maxn]; bool cmp(const Node& a,const Node& b) { return dcmp(a.x-b.x)==0? a.y < b.y : a.x < b.x; } struct Edge { ll x,y,v; }edge[2*maxn]; int tote; bool cmp3(const Edge& a,const Edge& b) { return a.v<b.v; } ll get_len(int x,int y) { return abs(px[x]-px[y])+abs(py[x]-py[y]); } void insert(int x,int y) { if(!x||!y||x==y) return ; // printf("insert:%d->%d ",x,y); ++tote; edge[tote].x=x; edge[tote].y=y; edge[tote].v=get_len(x,y); } int get_max(int x,int y) { if((ll)x*y==0) return x+y; if(!nowop) { if(px[x]+py[x]>px[y]+py[y]) return x; else return y; } if(nowop==1) { if(px[x]-py[x]>px[y]-py[y]) return x; else return y; } return 0; } int ql,qr,qx,maxnum[maxn]; void chge(int pos,int l,int r) { maxnum[pos]=get_max(maxnum[pos],qx); if(l==r) return; int mid=(l+r)>>1; if(ql<=mid) chge(pos<<1,l,mid); else chge(pos<<1|1,mid+1,r); } int q(int pos,int l,int r) { if(l>=ql&&r<=qr) return maxnum[pos]; int mid=(l+r)>>1; if(qr<=mid) return q(pos<<1,l,mid); if(ql>mid) return q(pos<<1|1,mid+1,r); return get_max(q(pos<<1,l,mid),q(pos<<1|1,mid+1,r)); } void clear(int pos,int l,int r) { maxnum[pos]=0; if(l==r) return; int mid=(l+r)>>1; clear(pos<<1,l,mid); clear(pos<<1|1,mid+1,r); } void doit() { For(i,1,n) node[i].id=i,p[i]=node[i].y; sort(p+1,p+n+1); sort(node+1,node+n+1,cmp); For(i,1,n) { int pos=lower_bound(p+1,p+n+1,node[i].y)-p; ql=1; qr=pos; insert(q(1,1,n),node[i].id); ql=qr=pos; qx=node[i].id; chge(1,1,n); } } /////////////////////// int fir[maxn],nxt[2*maxn],to[2*maxn],e=0;ll v[2*maxn]; void add(int x,int y,ll z) { // printf("add:%d->%d v:%lld ",x,y,z); to[++e]=y;nxt[e]=fir[x];fir[x]=e;v[e]=z; to[++e]=x;nxt[e]=fir[y];fir[y]=e;v[e]=z; sumtot+=z; } int pp[maxn]; int find(int x){ return x==pp[x]? x:pp[x]=find(pp[x]); } void Kru() { sort(edge+1,edge+tote+1,cmp3); For(i,1,n) pp[i]=i; int xx,yy,tot=0; For(i,1,tote) { xx=find(edge[i].x); yy=find(edge[i].y); if(xx!=yy) { add(edge[i].x,edge[i].y,edge[i].v); ++tot; if(tot==n-1) break; pp[xx]=yy; } } } int fa[maxn][maxt],dep[maxn];ll maxlen[maxn][maxt]; void dfs(int pos,int f) { fa[pos][0]=f; dep[pos]=dep[f]+1; For(i,1,W) { fa[pos][i]=fa[fa[pos][i-1]][i-1]; maxlen[pos][i]=max(maxlen[pos][i-1],maxlen[fa[pos][i-1]][i-1]); } int y,z; for(y=fir[pos];y;y=nxt[y]) { if((z=to[y])==f) continue; maxlen[z][0]=v[y]; dfs(z,pos); } } ll Yth(int x,int y) { if(fa[x][0]==y||fa[y][0]==x) return get_len(x,y); ll rs=0; if(dep[x]!=dep[y]) { if(dep[x]<dep[y]) swap(x,y); Rep(i,W,0) if(dep[fa[x][i]]>=dep[y]) rs=max(rs,maxlen[x][i]),x=fa[x][i]; } if(x==y) return rs; Rep(i,W,0) if(fa[x][i]!=fa[y][i]) { rs=max(rs,maxlen[x][i]); rs=max(rs,maxlen[y][i]); x=fa[x][i]; y=fa[y][i]; } rs=max(rs,maxlen[x][0]); rs=max(rs,maxlen[y][0]); return rs; } int main() { read(n); For(i,1,n) {read(px[i]); read(py[i]);} ////////////////////add edge //West - South For(i,1,n) { node[i].x=px[i]-py[i]; node[i].y=py[i]; } doit(); //South - West clear(1,1,n); For(i,1,n) { node[i].x=px[i]; node[i].y=py[i]-px[i]; } doit(); //West - North clear(1,1,n); nowop=1; For(i,1,n) { node[i].x=px[i]+py[i]; node[i].y=py[i]; node[i].y=INF-node[i].y; } doit(); //North - West clear(1,1,n); nowop=1; For(i,1,n) { node[i].x=px[i]; node[i].y=px[i]+py[i]; node[i].y=INF-node[i].y; } doit(); /////////////////// Kru(); dfs(1,0); read(m); int x,y; For(i,1,m) { read(x); read(y); printf("%lld ",sumtot-Yth(x,y)+get_len(x,y)); } return 0; }
最大权闭合子图(bzoj3996)
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; #define ll long long #define db double #define For(i,a,b) for(int i=(a);i<=(b);++i) #define Rep(i,a,b) for(int i=(a);i>=(b);--i) const int maxn=1007*1007,INF=0x3f3f3f3f; int n,S,T,D[maxn]; bool vis[maxn]; char cc; ll ff; template<typename T>void read(T& aa) { aa=0;cc=getchar();ff=1; while((cc<'0'||cc>'9')&&cc!='-') cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff; } struct Node{ int x,y,cap,flow; Node(){} Node(int x,int y,int cap):x(x),y(y),cap(cap){flow=0;} }node[2*maxn]; int fir[maxn],nxt[2*maxn],e=1; void add(int x,int y,int z) { node[++e]=Node(x,y,z);nxt[e]=fir[x];fir[x]=e; node[++e]=Node(y,x,0);nxt[e]=fir[y];fir[y]=e; } int dis[maxn],zz[maxn]; bool BFS() { memset(dis,-1,sizeof(dis)); int x,y,z,s=1,t=0; zz[++t]=S; dis[S]=0; while(s<=t) { x=zz[s++]; if(x==T) return 1; for(y=fir[x];y;y=nxt[y]) { if(dis[z=node[y].y]!=-1||node[y].flow>=node[y].cap) continue; dis[z]=dis[x]+1; zz[++t]=z; } } return 0; } int DFS(int pos,int maxf) { if(pos==T||maxf==0) return maxf; int rs=0,now,y,z; for(y=fir[pos];y&&maxf;y=nxt[y]) { if(dis[z=node[y].y]!=dis[pos]+1||node[y].flow>=node[y].cap) continue; now=DFS(z,min(maxf,node[y].cap-node[y].flow)); node[y].flow+=now; node[y^1].flow-=now; rs+=now; maxf-=now; } if(!rs) dis[pos]=-1; return rs; } void Dinic() { int rs=0; while(BFS()) rs+=DFS(S,INF); } void dfs(int pos) { if(vis[pos]) return; vis[pos]=1; for(int y=fir[pos];y;y=nxt[y]) { if(node[y].flow>=node[y].cap) continue; dfs(node[y].y); } } int main() { read(n); int x,y,z; S=n*n+n+1; T=S+1; For(i,1,n*n) { read(x); add(S,i,x); } For(i,1,n) { read(D[i]); add(i+n*n,T,D[i]); } For(i,1,n) For(j,1,n) { add((i-1)*n+j,i+n*n,INF); if(i!=j) add((i-1)*n+j,j+n*n,INF); } Dinic(); dfs(S); int ans=0; for(y=fir[S];y;y=nxt[y]) { if(vis[z=node[y].y]) ans+=node[y].cap; } For(i,1,n) if(vis[i+n*n]) ans-=D[i]; printf("%d",ans); return 0; }
朱刘算法
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; #define ll long long #define db double #define For(i,a,b) for(register int i=(a);i<=(b);++i) #define Rep(i,a,b) for(register int i=(a);i>=(b);--i) const int maxn=1000+7,maxm=1e6+7; const ll INF=1e18,inf=1e14; int n,m; ll dis[maxn][maxn]; char cc;ll ff; template<typename T>void read(T& aa) { aa=0;ff=1; cc=getchar(); while(cc!='-'&&(cc<'0'||cc>'9')) cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff; } struct Edge{ int x,y; ll w; Edge(){} Edge(int x,int y,ll w):x(x),y(y),w(w){} }edge[maxm]; int e; ll d[maxn]; int pr[maxn],id[maxn],vis[maxn]; ll zl(int rt,int n) { ll rs=0; int x,y,toth; while(1) { For(i,1,n) d[i]=INF; d[rt]=0; For(i,1,e) { x=edge[i].x; y=edge[i].y; if(x!=y&&edge[i].w<d[y]) { d[y]=edge[i].w; pr[y]=x; } } For(i,1,n) if(d[i]==INF) return -1; For(i,1,n) vis[i]=id[i]=-1; toth=0; For(i,1,n) { x=i; rs+=d[x]; while(id[x]==-1&&x!=rt&&vis[x]!=i) { vis[x]=i; x=pr[x]; } if(id[x]==-1&&x!=rt) { id[x]=++toth; for(y=pr[x];y!=x;y=pr[y]) id[y]=toth; } } if(!toth) break; For(i,1,n) if(id[i]==-1) id[i]=++toth; For(i,1,e) { x=edge[i].x; y=edge[i].y; if(id[x]!=id[y]) edge[i].w-=d[y]; edge[i].x=id[x]; edge[i].y=id[y]; } n=toth; rt=id[rt]; } if(rs-inf>=inf) return -1; return rs-inf; } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); read(n); read(m); For(i,1,n+1) For(j,1,n+1) dis[i][j]=INF; int x,y; ll w; For(i,1,m) { read(x); read(y); read(w); dis[x][y]=min(dis[x][y],w); } For(i,1,n) For(j,1,n) if(dis[i][j]!=INF) edge[++e]=Edge(i,j,dis[i][j]); For(i,1,n) edge[++e]=Edge(n+1,i,inf); printf("%lld ",zl(n+1,n+1)); return 0; }