【模板】其他算法
随机化
模拟退火
//Author:RingweEH
//P5544 [JSOI2016]炸弹攻击1
const int N=11,M=1010;
const double delta=0.996,Te=1e-10; //D和最终温度
int n,m,x[N],y[N],r[N],p[M],q[M],R,ansout=0;
double ansx,ansy;
double dis( double ax,double ay,double bx,double by ) //求两点间距离
{
double res=(bx-ax)*(bx-ax)+(by-ay)*(by-ay);
res=sqrt(res);
return res;
}
int calc( double xx,double yy ) //估价函数
{
double nowr=R;
for ( int i=1; i<=n; i++ )
nowr=min( nowr,dis(xx,yy,x[i],y[i])-(double)r[i] );
int cnt=0;
for ( int i=1; i<=m; i++ )
if ( dis(xx,yy,p[i],q[i])<=nowr ) cnt++;
return cnt;
}
void SA()
{
double T=6000; //初始温度
int ans=0;
while ( T>Te )
{
double nowx=ansx+(rand()*2-RAND_MAX)*T;
double nowy=ansy+(rand()*2-RAND_MAX)*T;
int nowans=calc( nowx,nowy );
int DelE=nowans-ans;
if ( DelE>0 ) ansx=nowx,ansy=nowy,ans=nowans,ansout=max( ansout,ans );
//更优的解,必然接受
else if ( exp(DelE/sqrt(T))>(double)rand()/1215 ) ansx=nowx,ansy=nowy,ans=nowans;
//按概率接受,保证了越到后期,和最优解的差距越大,越难被接受
T*=delta;
}
}
int main()
{
srand(time(0)); ansx=ansy=0;
n=read(); m=read(); R=read();
for ( int i=1; i<=n; i++ )
x[i]=read(),y[i]=read(),r[i]=read();
for ( int i=1; i<=m; i++ )
p[i]=read(),q[i]=read(),ansx+=x[i],ansy+=y[i];
ansx/=m; ansy/=m; ansout=calc( ansx,ansy );
while ( (double)clock()/CLOCKS_PER_SEC<=0.85 ) SA();
printf( "%d",ansout );
}
分治
整体二分
//Author: RingweEH
//P2617 Dynamic Rankings
#define lowbit(x) ((x)&(-x))
const int N=1e5+10,INF=0x3f3f3f3f;
int n,m,a[N],tr[N],ans[N],tot=0;
struct Operation
{
int tim,opt,l,r,val;
Operation( int _tim=0,int _opt=0,int _l=0,int _r=0,int _val=0 )
: tim(_tim),opt(_opt),l(_l),r(_r),val(_val) {}
//opt=0(insert),1(delete),2(query)
//val:insert x,query rk k;
}q[N*3],le[N*3],ri[N*3];
void Add( int x,int v ) { for(;x<=n;x+=lowbit(x)) tr[x]+=v; }
int Query(int x){int res=0;for(;x;x-=lowbit(x))res+=tr[x];return res;}
void Solve( int ql,int qr,int l,int r )
{//二分询问和答案,插入删除直接做,查询如果比rk小那么答案就在右区间,否则在左区间。
if ( l==r )
{
for ( int i=ql; i<=qr; i++ )
if ( q[i].opt==2 ) ans[q[i].tim]=l;
return;
}
int mid=(l+r)>>1,lcnt=0,rcnt=0,i,tmp;
for ( i=ql; i<=qr; i++ )
{
if ( q[i].opt==0 ) //insert
{
if ( q[i].val<=mid ) le[++lcnt]=q[i],Add(q[i].l,1);
else ri[++rcnt]=q[i];
}
else if ( q[i].opt==1 ) //detele
{
if ( q[i].val<=mid ) le[++lcnt]=q[i],Add(q[i].l,-1);
else ri[++rcnt]=q[i];
}
else //query
{
tmp=Query(q[i].r)-Query(q[i].l-1);
if ( tmp<q[i].val ) q[i].val-=tmp,ri[++rcnt]=q[i];
else le[++lcnt]=q[i];
}
}
for ( i=1; i<=lcnt; i++ ) //recover
{
q[ql+i-1]=le[i];
if ( le[i].opt==0 ) Add(le[i].l,-1);
else if ( le[i].opt==1 ) Add(le[i].l,1);
}
for ( i=1; i<=rcnt; i++ ) q[ql+lcnt+i-1]=ri[i];
if ( lcnt ) Solve(ql,ql+lcnt-1,l,mid);
if ( rcnt ) Solve(ql+lcnt,qr,mid+1,r);
}
int main()
{
scanf("%d%d",&n,&m);
for ( int i=1; i<=n; i++ ) scanf("%d",&a[i]),q[++tot]=Operation(0,0,i,i,a[i]);
int lcnt=0,rcnt=0,x,y,rk; char s[2];
for ( int i=1; i<=m; i++ )
{
scanf( "%s",s );
if ( s[0]=='C' )
{
lcnt++; scanf( "%d%d",&x,&y );
q[++tot]=Operation(lcnt,1,x,x,a[x]);
q[++tot]=Operation(lcnt,0,x,x,y);
a[x]=y;
}
if ( s[0]=='Q' )
{
rcnt++; scanf("%d%d%d",&x,&y,&rk);
q[++tot]=Operation(rcnt,2,x,y,rk);
}
}
Solve(1,tot,0,INF);
for ( int i=1 ;i<=rcnt; i++ ) printf("%d\n",ans[i] );
return 0;
}
CDQ分治(三维偏序)
//Author: RingweEH
//P3810 【模板】三维偏序(陌上花开)
#define lowbit(x) ((x)&(-x))
const int N=1e5+10,K=2e5+10;
struct Node{ int x,y,z,res,sam; }a[N],b[N];
int n,m,f[K],tr[K],k;
bool cmp3(Node t1,Node t2){return (t1.x==t2.x) ? ((t1.y==t2.y) ? t1.z<t2.z:t1.y<t2.y):t1.x<t2.x;}
bool cmp2(Node t1,Node t2){return (t1.y==t2.y) ? t1.z<t2.z : t1.y<t2.y; }
void Add( int x,int v ) { for ( ;x<=k;x+=lowbit(x))tr[x]+=v; }
int Query( int x ) { int res=0;for(;x;x-=lowbit(x))res+=tr[x]; return res;}
void CDQ_Conq( int l,int r )
{
if ( l==r ) return;
int mid=(l+r)>>1,i=mid+1,j=l;
CDQ_Conq(l,mid); CDQ_Conq(mid+1,r);
sort(a+l,a+mid+1,cmp2); sort(a+mid+1,a+r+1,cmp2);
for ( ; i<=r; i++ )
{
while ( a[j].y<=a[i].y && j<=mid ) Add(a[j].z,a[j].sam),j++;
a[i].res+=Query(a[i].z);
}
for ( i=l; i<j; i++ ) Add(a[i].z,-a[i].sam);
}
int main()
{
m=read(); k=read(); n=0;
for ( int i=1; i<=m; i++ ) b[i].x=read(),b[i].y=read(),b[i].z=read();
sort(b+1,b+1+m,cmp3); int cnt=0;
for ( int i=1; i<=m; i++ )
{
cnt++;
if ( (b[i].x^b[i+1].x) || (b[i].y^b[i+1].y) || (b[i].z^b[i+1].z) )
a[++n]=b[i],a[n].sam=cnt,cnt=0,a[n].res=0;
}
CDQ_Conq(1,n);
for ( int i=1; i<=n; i++ ) f[a[i].res+a[i].sam-1]+=a[i].sam;
for ( int i=0; i<m; i++ ) printf("%d\n",f[i] );
return 0;
}
CDQ套CDQ(四维偏序)
//Author: RingweEH
//P5621 [DBOI2019]德丽莎世界第一可爱
#define lowbit(x) ((x)&(-x))
const int N=5e4+10;
struct Node { int a,b,c,d,id; bool typ; ll mx,val; }a[N],b[N];
int n,id1[N],id2[N],tmp[N],tot;
ll tr[N];
bool operator == ( Node t1,Node t2 )
{ return t1.a==t2.a && t1.b==t2.b && t1.c==t2.c && t1.d==t2.d; }
bool cmp1( Node t1,Node t2 )
{
return (t1.a^t2.a) ? t1.a<t2.a :
(t1.b^t2.b) ? t1.b<t2.b :
(t1.c^t2.c) ? t1.c<t2.c :
t1.d<t2.d;
}
bool cmp2( Node t1,Node t2 )
{
return (t1.b^t2.b) ? t1.b<t2.b :
(t1.c^t2.c) ? t1.c<t2.c :
(t1.d^t2.d) ? t1.d<t2.d :
t1.a<t2.a;
}
bool cmp3( Node t1,Node t2 )
{
return (t1.c^t2.c) ? t1.c<t2.c :
(t1.d^t2.d) ? t1.d<t2.d :
(t1.a^t2.a) ? t1.a<t2.a :
t1.b<t2.b;
}
void Add( int x,ll val ){ for (;x<=tot; x+=lowbit(x)) if (tr[x]<val) tr[x]=val;else return;}
ll Query( int x ) { ll res=0;for(;x;x-=lowbit(x)) bmax(res,tr[x]); return res;}
void Clear(int x){ for (;x<=tot;x+=lowbit(x)) if ( tr[x] ) tr[x]=0; else return; }
void CDQ_Son( int l,int r )
{
if ( l==r ) return;
int mid=(l+r)>>1; CDQ_Son(l,mid);
sort(a+l,a+mid+1,cmp3); sort(a+mid+1,a+r+1,cmp3);
int i=mid+1,j=l;
while ( i<=r && j<=mid )
{
if ( a[j].c<=a[i].c )
{ if ( a[j].typ ) Add( a[j].d,a[j].mx ); j++; }
else
{ if ( !a[i].typ ) bmax( a[i].mx,Query(a[i].d)+a[i].val); i++; }
}
while ( i<=r ) { if ( !a[i].typ ) bmax( a[i].mx,Query(a[i].d)+a[i].val); i++; }
for ( int i=l; i<j; i++ ) if ( a[i].typ ) Clear(a[i].d);
for ( int i=l; i<=r; i++ ) b[id2[a[i].id]]=a[i];
for ( int i=l; i<=r; i++ ) a[i]=b[i];
CDQ_Son(mid+1,r);
}
void CDQ( int l,int r )
{
if ( l==r ) return;
int mid=(l+r)>>1; CDQ(l,mid);
for ( int i=l; i<=r; i++ ) a[i].typ=(i<=mid);
sort( a+l,a+r+1,cmp2 );
for ( int i=l; i<=r; i++ ) id2[a[i].id]=i;
CDQ_Son(l,r);
for ( int i=l; i<=r; i++ ) b[id1[a[i].id]]=a[i];
for ( int i=l; i<=r; i++ ) a[i]=b[i];
CDQ(mid+1,r);
}
int main()
{
n=read();
for ( int i=1; i<=n; i++ )
a[i].a=read(),a[i].b=read(),a[i].c=read(),a[i].d=read(),a[i].val=read(),tmp[i]=a[i].d;
sort(tmp+1,tmp+n+1);
tot=unique(tmp+1,tmp+1+n)-tmp-1;
sort(a+1,a+1+n,cmp1);
for ( int i=1; i<=n; i++ )
a[i].d=lower_bound(tmp+1,tmp+tot+1,a[i].d)-tmp;
int cnt=0;
for ( int i=1; i<=n; i++ )
if ( a[i]==a[i-1] ) a[cnt].val+=max(a[i].val,0ll);
else a[++cnt]=a[i];
n=cnt;
for ( int i=1; i<=n; i++ )
a[i].mx=a[i].val,a[i].id=id1[i]=i;
CDQ(1,n);
ll ans=-1e18;
for ( int i=1; i<=n; i++ ) bmax( ans,a[i].mx );
printf("%lld\n",ans );
return 0;
}
?
DDP
//Author: RingweEH
//P4719 【模板】"动态 DP"&动态树分治
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
#define db double
using namespace std;
int min( int a,int b ) { return a<b ? a : b; }
int max( int a,int b ) { return a>b ? a : b; }
void bmax( int &a,int b ) { a=(a>b) ? a : b; }
void bmin( int &a,int b ) { a=(a<b) ? a : b; }
const int L=1<<20;
char buf[L],*p1,*p2;
#define getchar() (p1==p2?(p2=buf+fread(p1=buf,1,L,stdin),p1==p2?EOF:*p1++):*p1++)
int read()
{
int x=0,w=1; char ch=getchar();
while ( ch>'9' || ch<'0' ) { if ( ch=='-' ) w=-1; ch=getchar(); }
while ( ch<='9' && ch>='0' ) x=x*10+ch-'0',ch=getchar();
return x*w;
}
#define ls pos<<1
#define rs pos<<1|1
const int N=1e5+1,M=2e5+1,NM=4e5+1,INF=0x3f3f3f3f;
int tot,head[N],n,m,tim,f[N][2];
int a[N],fa[N],siz[N],dep[N],dfn[N],id[N];
int wson[N],top[N],ed[N];
struct Matrix
{
int mat[2][2];
Matrix(){memset(mat,-0x3f,sizeof(mat));}
}val[N];
Matrix operator * ( Matrix A,Matrix B )
{
Matrix res;
for ( int k=0; k<2; k++ )
for ( int i=0; i<2; i++ )
for ( int j=0; j<2; j++ )
bmax(res.mat[i][j],A.mat[i][k]+B.mat[k][j]);
return res;
}
struct Edge { int to,nxt; }e[M];
void Adde( int u,int v ) { e[++tot].to=v; e[tot].nxt=head[u]; head[u]=tot; }
struct SegmentTree
{
int le[NM],ri[NM];
Matrix tr[NM];
inline void Pushup( int pos ) { tr[pos]=tr[ls]*tr[rs]; }
void Build( int pos,int l,int r )
{
le[pos]=l; ri[pos]=r;
if ( l==r ) { tr[pos]=val[dfn[l]]; return; }
int mid=l+r>>1;
Build(ls,l,mid); Build(rs,mid+1,r); Pushup(pos);
}
void Modify( int pos,int x )
{
if ( le[pos]==ri[pos] ) { tr[pos]=val[dfn[x]]; return; }
int mid=(le[pos]+ri[pos])>>1;
(x<=mid) ? Modify(ls,x) : Modify(rs,x); Pushup(pos);
}
Matrix Query( int pos,int L,int R )
{
if ( le[pos]==L && ri[pos]==R ) return tr[pos];
int mid=(le[pos]+ri[pos])>>1;
if ( R<=mid ) return Query(ls,L,R);
else if ( L>mid ) return Query(rs,L,R);
else return Query(ls,L,mid)*Query(rs,mid+1,R);
}
}Tr;
void DFS1( int u )
{
siz[u]=1;
for ( int i=head[u]; i; i=e[i].nxt )
{
int v=e[i].to;
if ( v==fa[u] ) continue;
fa[v]=u; dep[v]=dep[u]+1; DFS1(v);
siz[u]+=siz[v];
if ( siz[v]>siz[wson[u]] ) wson[u]=v;
}
}
void DFS2( int u,int lin )
{
id[u]=++tim; dfn[tim]=u; top[u]=lin; bmax(ed[lin],tim);
f[u][0]=0; f[u][1]=a[u];
val[u].mat[0][0]=val[u].mat[0][1]=0; val[u].mat[1][0]=a[u];
if ( wson[u]^0 )
{
DFS2(wson[u],lin);
f[u][0]+=max(f[wson[u]][0],f[wson[u]][1] ); f[u][1]+=f[wson[u]][0];
}
for ( int i=head[u]; i; i=e[i].nxt )
{
int v=e[i].to;
if ( v==fa[u] || v==wson[u] ) continue;
DFS2(v,v);
f[u][0]+=max(f[v][0],f[v][1]); f[u][1]+=f[v][0];
val[u].mat[0][1]=val[u].mat[0][0]+=max(f[v][0],f[v][1]);
val[u].mat[1][0]+=f[v][0];
}
}
void Update( int x,int y )
{
val[x].mat[1][0]+=y-a[x]; a[x]=y;
Matrix pre,las;
while ( x^0 )
{
pre=Tr.Query(1,id[top[x]],ed[top[x]]);
Tr.Modify(1,id[x]);
las=Tr.Query(1,id[top[x]],ed[top[x]]);
x=fa[top[x]];
val[x].mat[0][0]+=max(las.mat[0][0],las.mat[1][0])-max(pre.mat[0][0],pre.mat[1][0]);
val[x].mat[0][1]=val[x].mat[0][0]; val[x].mat[1][0]+=las.mat[0][0]-pre.mat[0][0];
}
}
int main()
{
//freopen( "exam.in","r",stdin );
n=read(); m=read();
for ( int i=1; i<=n; i++ ) a[i]=read();
for ( int i=1,u,v; i<n; i++ ) u=read(),v=read(),Adde(u,v),Adde(v,u);
DFS1(1); DFS2(1,1);
Tr.Build(1,1,n); Matrix ans;
for ( int i=1,x,y; i<=m; i++ )
{
x=read(); y=read();
Update(x,y); ans=Tr.Query(1,id[1],ed[1]);
printf("%d\n",max(ans.mat[0][0],ans.mat[1][0]) );
}
return 0;
}
大地也该是从一片类似的光明中冒出来的。