8.20总结
Blue Mary的战役地图
\(solution\)
暴力卡常
时间复杂度较高\(O(n^7)\)
优化后可过:
倒叙枚举边长,一旦找到就输出
AC Code
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
const int N=55;
int n;
int a[N][N],b[N][N];
bool dfs(int x,int y,int k)
{
for(int i=1;i<=n-k+1;i++)
{
for(int j=1;j<=n-k+1;j++)
{
if(b[i][j]==a[x][y])
{
int o=0;
for(int s=0;s<k;s++)
{
for(int w=0;w<k;w++)
{
if(a[x+s][y+w]!=b[i+s][j+w])
{
o=1;
break;
}
}
if(o==1)break;
}
if(o==0)return true;
}
}
}
return false;
}
int main()
{
// freopen("map.in","r",stdin);
// freopen("map.out","w",stdout);
n=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
b[i][j]=read();
int ans=0;
for(int k=n;k>=1;k--)
{
for(int i=1;i<=n-k+1;i++)
{
for(int j=1;j<=n-k+1;j++)
{
if(dfs(i,j,k))
{
ans=k;
printf("%d\n",ans);
return 0;
}
}
}
}
return 0;
}
无界单词
\(solution\)
对于总的无界单词的个数,我们考虑用dp来解决。
设计状态\(f_i\)表示长度为i的无界单词个数,由此可得转移方程为:\(f_i=2^{i}-\sum_{j=1}^{i/2}{f_{j}*2^{i-2*j}}\)
然后我们来考虑第k小的无界单词
kmp预处理+dp找在已经确定了len长的串后的无界单词个数
转移方程为:\(f_{i}=2^{i-len}-\sum_{j=1}^{i/2}{a_j}\)
分类讨论:
- \(len\leq j,a_j=f_{j}*2^{i-j*2}\)
- 否则\(len\leq i-j,a_j=f_j*2^{i-len-j}\)
- 否则,判断\(w_{1\cdots len-i+j}\)和\(w_{1\cdots len}\)是否相等,如果不相等\(w_j=1,k-=f[n]\)
通过帮助zcy,我知道了位移64位等于位移0位,所以一定要有数组预处理2的i次幂
AC Code
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
inline ull read()
{
ull x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
ull t,n,k,qow[100];
ull nex[100],w[100],f[100];
void kmp(int len)
{
for(int i=2,j=0;i<=len;i++)
{
while(j>0&&w[j+1]!=w[i])j=nex[j];
if(w[j+1]==w[i])j++;
nex[i]=j;
}
}
ull init(int len)
{
memset(f,0,sizeof f);
for(int i=1;i<=n;i++)
{
if(i<=len)
{
f[i]=!nex[i];
continue;
}
f[i]=qow[i-len];
for(int j=1;j<=i/2;j++)
{
if(j>=len)f[i]-=f[j]*qow[i-j*2];
else if(len<=i-j)f[i]-=f[j]*qow[i-len-j];
else if(f[j])
{
int o=0;
for(int s=1,p=i-j+1;p<=len;++p,++s)
{
if(w[s]!=w[p])
{
o=1;break;
}
}
if(!o)f[i]--;
}
}
}
return f[n];
}
int main()
{
// freopen("word.in","r",stdin);
// freopen("word.out","w",stdout);
t=read();
qow[0]=1;
for(int i=1;i<=64;i++)
qow[i]=qow[i-1]*2;
while(t--)
{
n=read(),k=read();
memset(f,0,sizeof f);
for(int i=1;i<=n;i++)
{
f[i]=qow[i];
for(int j=1;j<=i/2;j++)
f[i]-=f[j]*qow[i-2*j];
}
cout<<f[n]<<endl;
for(int i=1;i<=n;i++)
{
w[i]=0;kmp(i);
ull tmp=init(i);
if(tmp<k)w[i]=1,k-=tmp;
}
for(int i=1;i<=n;i++)
{
if(w[i]==1)printf("b");
else printf("a");
}
printf("\n");
}
return 0;
}
病毒感染
\(solution\)
Blue Mary开公司
\(solution\)
我们考虑用李超线段树来做这道题
建一棵[1,5e4]的线段树,对于一个区间上的节点,记录使这个区间收益最大的经营方案
每次有一个新的经营方案,就加入线段树中,如果这个区间的原方案完全高于新的方案,不做更改,如果原方案完全低于新的方案,就覆盖掉原方案。如果没有完全低于或完全高于,则下传。
查询时,因为没有上传,所以ans需比较所有包含x的区间的方案的值。
如果不写change,线段树会WA
AC Code
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+5;
const int M=5e4;
int n;
char opt[10];
struct ww{
int l,r;
double a,b;
}tr[N];
void build(int p,int l,int r)
{
tr[p].l=l,tr[p].r=r;
tr[p].a=tr[p].b=0;
if(l==r)return ;
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
}
void change(int p,int l,int r,double a,double b)
{
int l1=tr[p].l,r1=tr[p].r;
if(l<=l1&&r1<=r)
{
double yl=(l1-1)*tr[p].a+tr[p].b;
double yr=(r1-1)*tr[p].a+tr[p].b;
double yl_=(l1-1)*a+b;
double yr_=(r1-1)*a+b;
if(yl<=yl_&&yr<=yr_)
{
tr[p].a=a,tr[p].b=b;
return ;
}
if(yl>=yl_&&yr>=yr_)
return ;
}
int mid=(l1+r1)>>1;
if(l<=mid)change(p<<1,l,r,a,b);
if(r>mid)change(p<<1|1,l,r,a,b);
}
double ask(int p,int x,double ans)
{
ans=max(ans,(x-1)*tr[p].a+tr[p].b);
if(tr[p].l==tr[p].r&&tr[p].l==x)
return ans;
int mid=(tr[p].l+tr[p].r)>>1;
if(x<=mid)return ask(p<<1,x,ans);
return ask(p<<1|1,x,ans);
}
int main()
{
// freopen("company.in","r",stdin);
// freopen("company.out","w",stdout);
scanf("%d",&n);
build(1,1,M);
double a,b;int x;
while(n--)
{
scanf("%s",opt);
if(opt[0]=='P')
{
cin>>b>>a;
change(1,1,M,a,b);
}
else
{
scanf("%d",&x);
printf("%d\n",(int)(ask(1,x,0)/100.0));
}
}
return 0;
}

浙公网安备 33010602011771号