题目链接
A-超越学姐爱字符串
简单递推式,简单推前几项就可以得到答案了,就是与斐波拉契数有关。
也可以dp递推。
dp[i][0]表示长度为 i 且最后一个字符是‘c’的情况数,dp[i][1]
表 示 长 度 为 i 且 最 后 一 个 字 符 是 ‘ y ’ 的 情 况 数 。
dp[i+1][0]=dp[i][1],dp[i+1][1]=dp[i][0]+dp[i][1]。
#include
using namespace std;
const int N=1e5+10;
typedef long long ll;
const ll mod=1e9+7;
ll f[N];
int main()
{
f[1]=1;
f[2]=2;
for(int i=3;i
B-美味果冻
这类题对于数学推导较差的很吃亏。
转换一下就是另一种分块了,分块还有另一种形式:https://blog.csdn.net/qq_41286356/article/details/94970115
下面题解参考来自:https://blog.csdn.net/oampamp1/article/details/102513734
/*妙*/
#include
using namespace std;
long long a[3000010];
const long long mod=1e9+7;
long long div2=500000004;
void init1(int k) {
for(int i = 1; i <= k; i++) {
a[i] = 1;
}
}
void init2(int k) {
for(int i = 1; i <= k; i++) {
a[i] = (a[i] * i) % mod;
}
}
long long f3(long long n)
{
long long sum=0;
init1(n);
for(long long j=1;j<=n;j++)
{
init2(n / j);
for(long long k=1;k<=n/j;k++)
{
long long l=min(n,(k+1)*j-1);
sum=(sum+((((l-k*j+1+mod)%mod)*(k*j+l)%mod)*div2%mod)*a[k]%mod)%mod;
}
}
return sum%mod;
}
int main()
{
int n;
cin >> n;
cout << f3(n);
return 0;
}
C-富豪凯匹配串
bitset的题。。
设一个最初的二进制d全为1.
当询问的串当前位置i是字符1.那么就去保存1的bitset去与运算一下。
以此类推。。。直到最后查询d还剩多少个1。
有点像闯关,每次有1就&1,有0就&0。。。直到最后是全部相等的,就能通关。
#include
using namespace std;
const int N=1e3+10;
bitsetst[N][2],t;
char s[N];
int n,m;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
{
scanf("%s",s+1);
for(int j=1;j<=m;++j)
{
if(s[j]=='1') st[j][1][i]=1;
else st[j][0][i]=1;
}
}
int q;
scanf("%d",&q);
while(q--)
{
scanf("%s",s+1);
for(int i=1;i<=n;++i) t[i]=1;
for(int i=1;i<=m;++i)
{
if(s[i]=='_') continue;
if(s[i]=='1') t&=st[i][1];
else t&=st[i][0];
}
printf("%d\n",t.count());
}
}
E-老瞎眼 pk 小鲜肉
线段树解决偏序问题的经典问题了。
处理出合法的贡献区间和询问区间。
两种区间混合,按L从大到小排序。
遇到贡献区间就往线段树上更新值。遇到询问区间,就询问区间内的最小值即可。
这题我数组开小了wa了三发,居然不是提醒runtime error
#include
using namespace std;
const int N=2e6+10;
typedef long long ll;
const int inf=0x3f3f3f3f;
struct node
{
int l,r,id;
};
int n,q;
int a,sum;
int vis[N];
int mi[4*N],ans[N];
vectorG;
bool cmp(node a,node b)
{
if(a.l!=b.l) return a.l>b.l;
return a.id>1;
if(pos<=mid) up(id<<1,l,mid,pos,val);
else up(id<<1|1,mid+1,r,pos,val);
mi[id]=min(mi[id<<1],mi[id<<1|1]);
}
int qu(int id,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr) return mi[id];
int mid=l+r>>1;
int res=inf;
if(ql<=mid)res=qu(id<<1,l,mid,ql,qr);
if(qr>mid)res=min(res,qu(id<<1|1,mid+1,r,ql,qr));
return res;
}
int main()
{
scanf("%d%d",&n,&q);
memset(vis,-1,sizeof(vis));
int l,r;
vis[0]=0;
for(int i=1;i<=n;++i)
{
scanf("%d",&a);
sum=sum^a;
if(vis[sum]!=-1)
{
l=vis[sum]+1;
r=i;
G.push_back({l,r,0});
}
vis[sum]=i;
}
for(int i=1;i<=4*n;++i) mi[i]=inf;
for(int i=1;i<=q;++i)
{
int l,r;
scanf("%d%d",&l,&r);
G.push_back({l,r,i});
}
sort(G.begin(),G.end(),cmp);
for(node v:G)
{
if(v.id!=0) ans[v.id]=qu(1,1,n,1,v.r);
else up(1,1,n,v.r,v.r-v.l+1);
}
for(int i=1;i<=q;++i) {
if(ans[i]==inf) printf("-1\n");
else printf("%d\n",ans[i]);
}
}