# NOI考前乱写

//HDU 5046 Airport
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 110
#define MAXD MAXN*MAXN
#define INF 0x3f3f3f3f
#define LL "%lld"
typedef long long qword;
struct point
{
qword x,y;
};
point pl[MAXN];
qword dis(point p1,point p2)
{
return abs(p1.x-p2.x)+abs(p1.y-p2.y);
}
int L[MAXD],R[MAXD],U[MAXD],D[MAXD];
int ptr[MAXN];
int tot[MAXN];
int col[MAXD];
int topd=0;
void cover(int now)
{
for (int i=R[now];i!=now;i=R[i])
{
for (int j=U[i];j!=i;j=U[j])
{
L[R[j]]=L[j];
R[L[j]]=R[j];
}
}
for (int j=U[now];j!=now;j=U[j])
{
L[R[j]]=L[j];
R[L[j]]=R[j];
}
}
void recover(int now)
{
for (int i=R[now];i!=now;i=R[i])
for (int j=U[i];j!=i;j=U[j])
L[R[j]]=R[L[j]]=j;
for (int j=U[now];j!=now;j=U[j])
L[R[j]]=R[L[j]]=j;
}
int vv[MAXN];
int ff()
{
int ret=0;
vv[col[i]]=true;
{
if (vv[col[i]])
{
ret++;
for (int j=D[i];j!=i;j=D[j])
{
for (int k=R[j];k!=j;k=R[k])
{
vv[col[k]]=false;
}
}
}
}
return ret;
}
bool solve(int trst)
{
if (!trst)return false;
if (trst<ff())return false;
pair<int,int> mnv=make_pair(INF,0);
mnv=min(mnv,make_pair(tot[i],i));
int now=mnv.second;
for (int i=D[now];i!=now;i=D[i])
{
cover(i);
if (solve(trst-1))return true;
recover(i);
}
return false;
}

int main()
{
freopen("input.txt","r",stdin);
int nn;
int n,m;
int x,y,z;
scanf("%d",&nn);
int caseid=0;
while (nn--)
{
caseid++;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf(LL LL ,&pl[i].x,&pl[i].y);
memset(ptr,0,sizeof(ptr[0])*(n+10));
memset(tot,0,sizeof(tot[0])*(n+10));
qword l=-1,r=1ll<<33,mid;
while (l+1<r)
{
mid=(l+r)>>1;
topd=0;
for (int i=1;i<=n;i++)
{
int np=++topd;
col[np]=i;
L[R[np]]=np;
R[L[np]]=np;
D[np]=U[np]=np;
ptr[i]=np;
}
for (int i=1;i<=n;i++)
{
int last=0;
for (int j=1;j<=n;j++)
{
if (dis(pl[i],pl[j])<=mid)
{
int np=++topd;
col[np]=j;
tot[ptr[j]]++;
D[np]=ptr[j];
U[np]=U[ptr[j]];
D[U[np]]=U[D[np]]=np;
if (!last)
{
L[np]=R[np]=np;
}else
{
L[np]=last;
R[np]=R[last];
L[R[np]]=R[L[np]]=np;
}
last=np;
}
}
}
if (solve(m))
{
r=mid;
}else
{
l=mid;
}
}
printf("Case #%d: "LL"\n",caseid,r);
}
}

DLX分为精确覆盖和完全覆盖，两者的区别大概是在cover和recover之中。

//bzoj 1135
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 210000
#define MAXT MAXN*5
#define lch (now<<1)
#define rch (now<<1^1)
#define smid ((l+r)>>1)
typedef long long qword;
struct sgt_node
{
int lc,rc;
qword lx,rx,mx;
qword sum;
}sgt[MAXT];
void update(int now)
{
sgt[now].lx=max(sgt[lch].lx,sgt[lch].sum+sgt[rch].lx);
sgt[now].rx=max(sgt[rch].rx,sgt[rch].sum+sgt[lch].rx);
sgt[now].sum=sgt[lch].sum+sgt[rch].sum;
sgt[now].mx=max(max(sgt[lch].mx,sgt[rch].mx),sgt[lch].rx+sgt[rch].lx);
}
void Build_sgt(int now,int l,int r,int v)
{
if (l==r)
{
sgt[now].sum=v;
sgt[now].lx=sgt[now].rx=sgt[now].mx=v;
return ;
}
Build_sgt(lch,l,smid,v);
Build_sgt(rch,smid+1,r,v);
update(now);
}
void Modify_sgt(int now,int l,int r,int pos,int v)
{
if (l==r)
{
sgt[now].sum+=v;
sgt[now].lx+=v;
sgt[now].rx+=v;
sgt[now].mx+=v;
return ;
}
if (pos<=smid)
Modify_sgt(lch,l,smid,pos,v);
else
Modify_sgt(rch,smid+1,r,pos,v);
update(now);
}

int main()
{
freopen("input.txt","r",stdin);
int n,m,t,d;
int x,y;
scanf("%d%d%d%d",&n,&m,&t,&d);
Build_sgt(1,1,n,-t);
for (int i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
Modify_sgt(1,1,n,x,y);
if (sgt[1].mx>(qword)t*d)
{
printf("NIE\n");
}else
{
printf("TAK\n");
}
}

Hall

hall定理用于二分图匹配相关问题，在要求方案时用贪心或匈牙利算法，运用hall定理有利于优化时间复杂度。

//bzoj 3270
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cassert>
#include<cmath>
using namespace std;
#define MAXN 1010
#define MAXV MAXN
#define MAXE MAXN*20
typedef double real;
const real eps = 1e-7;

struct Edge
{
int np;
Edge *next;
}E[MAXE],*V[MAXV];
int tope=-1;
{
E[++tope].np=y;
E[tope].next=V[x];
V[x]=&E[tope];
}
real ps[MAXN];
real mat[MAXN][MAXN];
real res[MAXN];
int deg[MAXN];

int main()
{
freopen("input.txt","r",stdin);
int n,m;
int a,b;
int x,y,z;
scanf("%d%d",&n,&m);
scanf("%d%d",&a,&b);
a--;b--;
for (int i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
x--;y--;
deg[x]++;
deg[y]++;
}
for (int i=0;i<n;i++)
scanf("%lf",&ps[i]);
for (int i=0;i<n;i++)
{
for (int j=0;j<n;j++)
{
if (i==j)
{
mat[i*n+j][i*n+j]=1;
continue;
}
Edge *ne1,*ne2;
for (ne1=V[i];ne1;ne1=ne1->next)
for (ne2=V[j];ne2;ne2=ne2->next)
mat[ne1->np*n+ne2->np][i*n+j]=-1*(1-ps[i])*(1-ps[j])/deg[i]/deg[j];
Edge *ne;
for (ne=V[i];ne;ne=ne->next)
mat[ne->np*n+j][i*n+j]=-1*ps[j]*(1-ps[i])/deg[i];
for (ne=V[j];ne;ne=ne->next)
mat[i*n+ne->np][i*n+j]=-1*(1-ps[j])*ps[i]/deg[j];
mat[i*n+j][i*n+j]=1-ps[i]*ps[j];
mat[i*n+j][n*n]=0;
}
}
mat[a*n+b][n*n]=1;
int l=n*n;
for (int i=0;i<l;i++)
{
int x=-1;
for (int j=i;j<=l;j++)
{
if (abs(mat[j][i])>eps)
x=j;
}
assert(x!=-1);
if (x!=i)
for(int j=0;j<=l;j++)
swap(mat[i][j],mat[x][j]);
for (int j=i+1;j<l;j++)
{
real tmp=mat[j][i]/mat[i][i];
for (int k=i;k<=l;k++)
{
mat[j][k]-=mat[i][k]*tmp;
}
}
}
for (int i=l-1;i>=0;i--)
{
real tmp=mat[i][n*n];
for (int j=i+1;j<n*n;j++)
tmp-=res[j]*mat[i][j];
res[i]=tmp/mat[i][i];
}
for (int i=0;i<n;i++)
printf("%.6lf ",res[i*n+i]);
}

//Miller Rabin
//HDU 2138
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long qword;
qword pow_mod(qword x,qword y,int mod)
{
qword ret=1%mod;
while (y)
{
if (y&1)ret=ret*x%mod;
x=x*x%mod;
y>>=1;
}
return ret;
}

bool MillerRabin(qword a,int n)
{
int x=n-1,y=0;
while ((x&1)==0)x>>=1,y++;
a=pow_mod(a,x,n);
int pe=a;
for (int i=0;i<y;i++)
{
pe=a;
a=a*a%n;
if (a==1 && pe!=n-1 && pe!=1)return false;
}
return a==1?true:false;
}

int main()
{
//    freopen("input.txt","r",stdin);
int n;
int x;
int s[6]={2,3,5,7,17,61};
while (~scanf("%d",&n))
{
int ans=0;

for (int i=0;i<n;i++)
{
scanf("%d",&x);
if (x==1)
{
continue;
}else if (x==2)
{
ans++;
continue;
}
bool flag=true;
for (int j=0;j<6;j++)
{
if (s[j]>=x)continue;
if (!MillerRabin(s[j],x))
{
flag=false;
break;
}
}
if (flag)
{
ans++;
}
}
printf("%d\n",ans);

Miller Rabin

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
#define MAXN 110000
#define MAXM 210
#define BIG 1000000000000000LL
typedef long long qword;
int a[MAXN];
qword s[MAXN];
qword dp[2][MAXN];
struct point
{
qword x,y;
};
qword area(point p1,point p2,point p3)
{
return (p1.x-p2.x)*(p1.y-p3.y) - (p1.y-p2.y)*(p1.x-p3.x);
}
point q[MAXN];

int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
int n,m;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
//if (!a[i])i--,n--;
}
for (int i=1;i<=n;i++)
s[i]=s[i-1]+a[i];
for (int i=0;i<2;i++)
for (int j=0;j<=n;j++)
dp[i][j]=-BIG;
point pt;
dp[0][0]=0;
for (int i=1;i<=m;i++)
{
tail=-1;
for (int j=1;j<=n;j++)
{
pt.x=s[j-1];
pt.y=-s[n]*s[j-1]+dp[(i&1)^1][j-1];
{
if (area(q[tail-1],q[tail],pt)==0)
{
cout<<"haha"<<endl;
}
tail--;
}
q[++tail]=pt;
//                printf("%lld ",dp[i&1][j]);
}
dp[i&1][0]=-BIG;
//        printf("\n");
}
qword ans=0;
for (int i=1;i<=n;i++)
ans=max(ans,dp[m&1][i]);
printf("%lld\n",ans);
}

//POJ 1160
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 3100
#define MAXM 40
#define INF 0x3f3f3f3f
int w[MAXN][MAXN],w1[MAXN][MAXN];
int a[MAXN];
int dp[MAXM][MAXN];
pair<int,int> srange[MAXN];
int stack[MAXN];
int tops=-1;

int main()
{
freopen("input.txt","r",stdin);
int n,m;
int x,y,z;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",a+i);
for (int i=1;i<=n;i++)
{
for (int j=i;j<=n;j++)
{
if ((i+j)/2==(i+j-1)/2)
w[i][j]=w[i][j-1]+a[j]-a[(i+j)/2];
else
w[i][j]=w[i][j-1]+(a[(i+j)/2]-a[(i+j-1)/2])*(((i+j)/2-i) - (j-(i+j)/2))
+a[j]-a[(i+j)/2];
}
}
memset(dp,INF,sizeof(dp));
dp[0][0]=0;
srange[++tops]=make_pair(1,n);
stack[tops]=0;
for (int i=1;i<=m;i++)
{
while (~tops)
{
for (int j=srange[tops].first;j<=srange[tops].second;j++)
dp[i][j]=dp[i-1][stack[tops]]+w[stack[tops]+1][j];
tops--;
}
for (int j=1;j<=n;j++)
{
while (~tops && dp[i][j]+w[j+1][srange[tops].first]<dp[i][stack[tops]]+w[stack[tops]+1][srange[tops].first])
tops--;
if (~tops)
{
int l=srange[tops].first;
int r=srange[tops].second+1;
while (l+1<r)
{
int mid=(l+r)>>1;
if (dp[i][j]+w[j+1][mid]<dp[i][stack[tops]]+w[stack[tops]+1][mid])
r=mid;
else
l=mid;
}
srange[tops].second=l;
if (r<=n)
{
srange[++tops]=make_pair(r,n);
stack[tops]=j;
}
}else
{
srange[++tops]=make_pair(1,n);
stack[tops]=j;
}
}
}
int ans=dp[m][n];
printf("%d\n",ans);
return 0;
}
1D1D优化
//bzoj 1856
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MOD 20100403
#define MAXN 2001000
typedef long long qword;
qword fact[MAXN];
qword pow_mod(qword x,qword y)
{
qword ret=1;
while (y)
{
if (y&1)ret=ret*x%MOD;
x=x*x%MOD;
y>>=1;
}
return ret;
}
qword C(int x,int y)
{
if (x<y)return 0;
return fact[x]*pow_mod(fact[x-y],MOD-2)%MOD*pow_mod(fact[y],MOD-2)%MOD;
}

int main()
{
//freopen("input.txt","r",stdin);
int n,m;
scanf("%d%d",&n,&m);
fact[0]=1;
for (int i=1;i<=n+m;i++)
fact[i]=fact[i-1]*i%MOD;
qword ans=C(n+m,n)-C(n+m,n+1);
ans=(ans%MOD+MOD)%MOD;
printf("%d\n",(int)ans);
}
Catalan
Tarjan-缩点
Tarjan-边双&&非递归
Tarjan-点双

//bzoj 3339
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<set>
using namespace std;
#define MAXN 210000
#define smid ((l+r)>>1)
int n,m;
int a[MAXN];
int tmp[MAXN],prv[MAXN];
const int big=200000;
struct qur_t
{
int id,l,r,ans;
}qur[MAXN];
vector<qur_t> vec;
bool cmp_r(qur_t q1,qur_t q2)
{
return q1.r<q2.r;
}
int res[MAXN];
void solve(int l,int r,vector<qur_t> &vec)
{
if (l==r)
{
for (int i=0;i<vec.size();i++)
res[vec[i].id]=l;
return ;
}
vector<qur_t> v1,v2;
multiset<int> S;
sort(vec.begin(),vec.end(),cmp_r);
for (int i=l;i<=smid;i++)
S.insert(tmp[i]);
int cur=n;
for (int i=vec.size()-1;i>=0;i--)
{
while (vec[i].r<cur)
{
if (a[cur]<=smid && a[cur]>=l)
{
S.erase(S.find(cur));
S.insert(prv[cur]);
}
cur--;
}
if (*S.begin()<vec[i].l)
v1.push_back(vec[i]);
else
v2.push_back(vec[i]);
}
solve(l,smid,v1);
solve(smid+1,r,v2);
}

int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
int x,y,z;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
for (int i=1;i<=n;i++)
{
prv[i]=tmp[a[i]];
tmp[a[i]]=i;
}
for (int i=1;i<=m;i++)
{
scanf("%d%d",&qur[i].l,&qur[i].r);
qur[i].id=i;
}
vec.insert(vec.begin(),qur+1,qur+m+1);
solve(0,big+1,vec);
for (int i=1;i<=m;i++)
printf("%d\n",res[i]);

}

SBT && 动态凸包

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客