【比赛报告】2018.10.19 NOIP模拟赛卷十九
比赛时间:2018.10.19 选手:lrllrl 用时:2.5h 得分:10+0+30=40
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int n,m,a[1010][1010],dp[1010][1010][2],pre[1010][1010];
int num(int i,int j){return (i-1)*m+j;}
int main()
{
freopen("lemouse.in","r",stdin);
freopen("lemouse.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
memset(dp,0x3f,sizeof(dp));
dp[0][1][0]=dp[1][0][0]=dp[1][0][1]=dp[0][1][1]=a[1][1];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
dp[i][j][0]=min(dp[i-1][j][0]+a[i][j-1],dp[i-1][j][1])+a[i][j+1]+a[i+1][j];
dp[i][j][1]=min(dp[i][j-1][1]+a[i-1][j],dp[i][j-1][0])+a[i][j+1]+a[i+1][j];
}
printf("%d\n",min(dp[n][m][0],dp[n][m][1]));
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=3e4+10;
const int INF=0x3f3f3f3f;
int n,m,hd[N],r[N],tot,nowrank,dis[N],lim[N],stack[N],tp,top,ans,minr[N];
struct Edge{
int v,w,nx;
}e[N*10];
struct Heap{
int x,w;
Heap(void){}
Heap(int _x,int _w):x(_x),w(_w){}
}heap[100*N];
void add(int u,int v,int w)
{
e[++tot].v=v;
e[tot].w=w;
e[tot].nx=hd[u];
hd[u]=tot;
}
bool cmp(const Heap&a,const Heap&b)
{
return a.w>b.w||(a.w==b.w&&r[a.x]<r[b.x]);
}
void dijk()
{
while(top)
{
Heap sta=heap[1];
pop_heap(heap+1,heap+top+1,cmp);
top--;
if(sta.w!=dis[sta.x])continue;
stack[++tp]=sta.x;
for(int i=hd[sta.x];i;i=e[i].nx)
{
if(r[e[i].v]>nowrank)continue;
if(dis[e[i].v]>sta.w+e[i].w&&lim[e[i].v]>sta.w+e[i].w)
{
dis[e[i].v]=sta.w+e[i].w;
heap[++top]=Heap(e[i].v,dis[e[i].v]);
push_heap(heap+1,heap+top+1,cmp);
}
}
}
}
int main()
{
freopen("serves.in","r",stdin);
freopen("serves.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&r[i]);
for(int i=1,u,v,w;i<=m;i++)
scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,w);
memset(dis,0x3f,sizeof(dis));
memset(lim,0x3f,sizeof(lim));
for(int i=10;i;i--)
{
nowrank=i;
memset(minr,0x3f,sizeof(minr));
for(int j=1;j<=n;j++)
if(r[j]==i)
{
heap[++top]=Heap(j,0);
dis[j]=0;
dijk();
for(;tp;tp--)
{
int k=stack[tp];
if(lim[k]>dis[k])ans++;
minr[k]=min(minr[k],dis[k]);
dis[k]=INF;
}
}
for(int j=1;j<=n;j++)
lim[j]=min(minr[j],lim[j]);
}
printf("%d\n",ans);
return 0;
}
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1000010;
const ull mul=1333331;
int n,m,a[N],b[N],X[N],k;
ull hx[N],f[N]={1};
ll ans;
inline int bin(int x)
{
int l=1,r=k;
while(l<=r)
{
int mid=l+r>>1;
if(b[mid]<=x)l=mid+1;
else r=mid-1;
}
return r;
}
inline ull getHash(const int &l,const int &r)
{
return hx[r]-hx[l-1]*f[r-l+1];
}
inline int lcp(int x,int y)//求最长公共后缀
{
int l=0,r=min(n-x+1,n-y+1);
while(l<=r)
{
int mid=l+r>>1;
if(getHash(x,x+mid-1)==getHash(y,y+mid-1))l=mid+1;
else r=mid-1;
}
return r;
}
inline int anti_lcp(int x,int y)
{
int l=0,r=min(x,y);
while(l<=r)
{
int mid=l+r>>1;
if(getHash(x-mid+1,x)==getHash(y-mid+1,y))l=mid+1;
else r=mid-1;
}
return r;
}
int main()
{
freopen("weapon.in","r",stdin);
freopen("weapon.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),X[i]=a[i];
sort(X+1,X+n+1);
X[0]=~0U>>1;
for(int i=1;i<=n;i++)
if(X[i]!=X[i-1])
b[++k]=X[i];
for(int i=1;i<=n;i++)
a[i]=bin(a[i]);
for(int i=1;i<=n;i++)
f[i]=f[i-1]*mul;
for(int i=1;i<=n;i++)
hx[i]=hx[i-1]*mul+a[i];
for(int i=1;2*i+m<=n;i++)
{
int nowl=0;
for(int j=1;;)
{
int len=min(i,n-(j+i+m-1));
if(!len)break;
int frontl=lcp(j,j+i+m);
int backl=anti_lcp(j+len-1,j+m+i+len-1);
frontl=min(frontl,len);
backl=min(backl,len);
if(frontl==len)
{
if(nowl>=i)ans+=len;
else ans+=max(0,nowl+frontl-i+1);
nowl+=len;
}
else
{
if(nowl>=i)ans+=frontl;
else ans+=max(0,nowl+frontl-i+1);
nowl=backl;
}
j+=len;
}
}
cout<<ans<<endl;
return 0;
}
赛后总结
T1很傻逼的在那里大力分类讨论……这种DP多开一两维不是正常操作吗,这都想不到,DP实在太弱
T2一脸不可做,T3一脸不可做
总体来说自己还是太弱了,不要再颓了