A
随便构造即可
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair<int,int>
#define ll long long
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline ll readll(){
char ch=gc();
ll res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline int readstring(char *s){
int top=0;char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
return top;
}
template<typename tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
template<typename tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
cs int mod=1e9+7;
inline int add(int a,int b){return (a+=b)>=mod?(a-mod):a;}
inline int dec(int a,int b){a-=b;return a+(a>>31&mod);}
inline int mul(int a,int b){static ll r;r=1ll*a*b;return (r>=mod)?(r%mod):r;}
inline void Add(int &a,int b){(a+=b)>=mod?(a-=mod):0;}
inline void Dec(int &a,int b){a-=b,a+=a>>31&mod;}
inline void Mul(int &a,int b){static ll r;r=1ll*a*b;a=(r>=mod)?(r%mod):r;}
inline int ksm(int a,int b,int res=1){if(a==0&&b==0)return 0;for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
inline int Inv(int x){return ksm(x,mod-2);}
inline int fix(int x){return (x<0)?x+mod:x;}
int main(){
#ifdef Stargazer
freopen("lx.in","r",stdin);
#endif
int T=read();
while(T--){
int n=read();
if(n==1)puts("-1");
else{
if(n%3==0)
cout<<4;
if(n%3==1)
cout<<5;
if(n%3==2)
cout<<4;
for(int i=1;i<n;i++)cout<<3;
puts("");
}
}
}
B
模拟还原即可
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair<int,int>
#define ll long long
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline ll readll(){
char ch=gc();
ll res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline int readstring(char *s){
int top=0;char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
return top;
}
template<typename tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
template<typename tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
cs int mod=1e9+7;
inline int add(int a,int b){return (a+=b)>=mod?(a-mod):a;}
inline int dec(int a,int b){a-=b;return a+(a>>31&mod);}
inline int mul(int a,int b){static ll r;r=1ll*a*b;return (r>=mod)?(r%mod):r;}
inline void Add(int &a,int b){(a+=b)>=mod?(a-=mod):0;}
inline void Dec(int &a,int b){a-=b,a+=a>>31&mod;}
inline void Mul(int &a,int b){static ll r;r=1ll*a*b;a=(r>=mod)?(r%mod):r;}
inline int ksm(int a,int b,int res=1){if(a==0&&b==0)return 0;for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
inline int Inv(int x){return ksm(x,mod-2);}
inline int fix(int x){return (x<0)?x+mod:x;}
int n,a[200005],b[200005];
int main(){
#ifdef Stargazer
freopen("lx.in","r",stdin);
#endif
n=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int mx=0,i=1;i<=n;i++){
b[i]=mx+a[i];
chemx(mx,b[i]);
}
for(int i=1;i<=n;i++)cout<<b[i]<<" ";
}
C
显然选出最大的
k
k
k个作为答案
方案就是空隙长度之积
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair<int,int>
#define ll long long
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline ll readll(){
char ch=gc();
ll res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline int readstring(char *s){
int top=0;char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
return top;
}
template<typename tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
template<typename tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
cs int mod=998244353;
inline int add(int a,int b){return (a+=b)>=mod?(a-mod):a;}
inline int dec(int a,int b){a-=b;return a+(a>>31&mod);}
inline int mul(int a,int b){static ll r;r=1ll*a*b;return (r>=mod)?(r%mod):r;}
inline void Add(int &a,int b){(a+=b)>=mod?(a-=mod):0;}
inline void Dec(int &a,int b){a-=b,a+=a>>31&mod;}
inline void Mul(int &a,int b){static ll r;r=1ll*a*b;a=(r>=mod)?(r%mod):r;}
inline int ksm(int a,int b,int res=1){if(a==0&&b==0)return 0;for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
inline int Inv(int x){return ksm(x,mod-2);}
inline int fix(int x){return (x<0)?x+mod:x;}
cs int N=200005;
int n,k,a[N];
pii b[N];
int main(){
n=read(),k=read();
for(int i=1;i<=n;i++)b[i].fi=read(),b[i].se=i;
sort(b+1,b+n+1);
reverse(b+1,b+n+1);
ll res=0;
for(int i=1;i<=k;i++)res+=b[i].fi,a[i]=b[i].se;
sort(a+1,a+k+1);int ret=1;
for(int i=2;i<=k;i++)Mul(ret,a[i]-a[i-1]);
cout<<res<<" "<<ret<<'\n';
return 0;
}
D
脑残写了个没用的双哈希结果被卡了。。。
q
n
m
d
qnmd
qnmd
考虑先用
m
a
n
a
c
h
e
r
manacher
manacher求出每个位置
p
p
p为中心的最长回文长度
如果
p
≤
n
/
2
p\le n/2
p≤n/2那么
p
p
p为中心的最长回文子串前面的一定需要和后面一段后缀匹配
否则
p
p
p的最长回文子串后面剩下的一定会和一段前缀匹配
对于单双回文串分类判断一下
复杂度 O ( n ) O(n) O(n)
By Backseat-Stargazer, contest: Codeforces Global Round 7, problem: (D2) Prefix-Suffix Palindrome (Hard version), Accepted, #, Copy, hack it!
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair<int,int>
#define ll long long
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline ll readll(){
char ch=gc();
ll res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline int readstring(char *s){
int top=0;char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
return top;
}
template<typename tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
template<typename tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
int n,l,mxlen;
cs int N=2000005;
char s[N],t[N];
inline bool check(int p){
return p<=mxlen;
};
int len[N];
int main(){
#ifdef Stargazer
freopen("lx.in","r",stdin);
#endif
int T=read();
while(T--){
n=readstring(t);
mxlen=0;
for(int i=1;i<=n;i++)if(t[i]!=t[n-i+1]){break;}else mxlen=i;
l=0;
s[0]='!',s[l=1]='&';
for(int i=1;i<=n;i++)s[++l]=t[i],s[++l]='&';
s[l+1]='@';
for(int i=1,mxpos=0,r=0;i<=l;i++){
// cout<<s[i];
if(i<=r)len[i]=min(r-i+1,len[2*mxpos-i]);
while(s[i+len[i]]==s[i-len[i]])len[i]++;
if(i+len[i]-1>r)r=i+len[i]-1,mxpos=i;
}int res=0,p1=0,p2=0;
for(int i=1;i<=l;i++){
int le=len[i]-1,p=i/2;
if(i&1){
if(p<=n/2){
int cp=p-(le/2);
if(check(cp)&&res<cp*2+le){
res=cp*2+le,p1=p+(le/2),p2=n-cp+1;
}
}
else{
int cp=p+1+(le/2);
if(check(n-cp+1)&&res<2*(n-cp+1)+le){
res=(n-cp+1)*2+le,p1=n-cp+1,p2=p-(le/2)+1;
}
}
}
else{
if(p<=n/2){
int cp=p-(le/2)-1;
if(check(cp)&&res<cp*2+le){
res=cp*2+le,p1=p+(le/2),p2=n-cp+1;
}
}
else{
int cp=p+(le/2)+1;
if(check(n-cp+1)&&res<2*(n-cp+1)+le){
res=(n-cp+1)*2+le,p1=n-cp+1,p2=p-(le/2);
}
}
}
}
for(int i=1;i<=p1;i++)cout<<t[i];
for(int i=p2;i<=n;i++)cout<<t[i];
puts("");
for(int i=1;i<=l;i++)len[i]=0;
}
}
E
考虑对于每次操作维护答案没有容易的做法
考虑对于当前答案
x
x
x
如果答案变成了
x
−
1
x-1
x−1
那么一定满足对于每个位置
p
p
p
(
p
及
之
后
≥
x
的
数
的
数
量
)
≤
p
后
面
炸
弹
的
数
量
(p及之后\geq x的数的数量)\le p后面炸弹的数量
(p及之后≥x的数的数量)≤p后面炸弹的数量
即
f
p
=
(
p
及
之
后
≥
x
的
数
的
数
量
)
−
p
后
面
炸
弹
的
数
量
≤
0
f_p=(p及之后\geq x的数的数量)-p后面炸弹的数量\le0
fp=(p及之后≥x的数的数量)−p后面炸弹的数量≤0
又显然每次操作后答案一定是单调不增的
于是用线段树维护每个位置的
f
f
f
复杂度
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair<int,int>
#define ll long long
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline ll readll(){
char ch=gc();
ll res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline int readstring(char *s){
int top=0;char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
return top;
}
template<typename tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
template<typename tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
cs int N=300005;
int n,p[N],q[N],pos[N];
namespace Seg{
cs int N=::N<<2;
int mx[N],tag[N];
#define lc (u<<1)
#define rc ((u<<1)|1)
#define mid ((l+r)>>1)
void update(int u,int l,int r,int st,int des,int k){
if(st<=l&&r<=des)return tag[u]+=k,mx[u]+=k,void();
if(st<=mid)update(lc,l,mid,st,des,k);
if(mid<des)update(rc,mid+1,r,st,des,k);
mx[u]=max(mx[lc],mx[rc])+tag[u];
}
#undef lc
#undef rc
#undef mid
}
int main(){
#ifdef Stargazer
freopen("lx.in","r",stdin);
#endif
n=read();
for(int i=1;i<=n;i++)p[i]=read(),pos[p[i]]=i;
for(int i=1;i<=n;i++)q[i]=read();
int ans=n+1;
for(int i=1;i<=n;i++){
while(Seg::mx[1]<=0){
ans--;
Seg::update(1,1,n,1,pos[ans],1);
}
cout<<ans<<" ";
Seg::update(1,1,n,1,q[i],-1);
}return 0;
}
F
好像
e
a
s
y
easy
easy直接
n
2
2
n
n2^{2n}
n22n都可以过。。。
对于
h
a
r
d
hard
hard考虑容斥
记
a
n
s
s
t
a
ans_{sta}
anssta表示
s
t
a
sta
sta中
1
1
1满足
p
i
,
p
i
+
1
p_i,p_{i+1}
pi,pi+1一定相连,
0
0
0为可能相连可能不相连的方案数
如果有
a
n
s
ans
ans显然可以轻松知道答案
一个结论是对于一个状态
s
s
s的方案数
我们只关心里面连续的
1
1
1的段的长度的集合
例如
111011
111011
111011和
110111
110111
110111方案数是一样的
而段数的集合实际上是一个类似整数拆分
最多只有不到
400
400
400个
考虑先
d
p
dp
dp出
f
s
f_s
fs表示走了
s
s
s内的点的方案数
那么一个集合
v
1
,
v
2
,
.
.
.
.
v
k
v_1,v_2,....v_k
v1,v2,....vk的答案就是
∑
∏
i
,
c
n
t
[
m
i
]
=
v
i
f
m
i
\sum_{}\prod_{i,cnt[m_i]=v_i}f_{m_i}
∑∏i,cnt[mi]=vifmi
其中满足
∑
c
n
t
[
m
i
]
=
n
且
m
的
O
R
和
为
2
n
−
1
,
c
n
t
表
示
其
中
为
1
的
个
数
\sum cnt[m_i]=n且m的OR和为2^n-1,cnt表示其中为1的个数
∑cnt[mi]=n且m的OR和为2n−1,cnt表示其中为1的个数
由于有
∑
c
n
t
=
n
\sum cnt=n
∑cnt=n的限制不会出现某个点出现在多个
m
m
m内
这个直接一边枚举整数拆分一边乘就可以过了
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair<int,int>
#define ll long long
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline ll readll(){
char ch=gc();
ll res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline int readstring(char *s){
int top=0;char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
return top;
}
template<typename tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
template<typename tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
cs int N=19,M=(1<<N)+3;
int n,m,cnt[M];
ll val[M],ans[M],f[N][M],dp[M][N],s[M];
vector<int> e[N];
char str[N];
vector<int> now;
map<vector<int>,vector<int>> sta;
inline void calc(){
ll res=0;
for(int i=0;i<m;i++)
if(cnt[i^(m-1)]&1)res-=val[i];
else res+=val[i];
for(int &s:sta[now])
ans[s]+=res;
}
void dfs(int s,int mx){
if(s>n)return;
if(s==n)return calc();
vector<ll> pre(m);
for(int i=0;i<m;i++)pre[i]=val[i];
for(int i=mx;i+s<=n;i++){
if(s+i!=n&&s+i+i>n)continue;
now.pb(i);
for(int j=0;j<m;j++)
val[j]*=f[i][j];
dfs(s+i,i);
for(int j=0;j<m;j++)
val[j]=pre[j];
now.pop_back();
}
}
inline void fmt(ll *f,int lim){
for(int mid=1;mid<lim;mid<<=1)
for(int i=0;i<lim;i+=mid<<1)
for(int j=0;j<mid;j++)
f[i+j+mid]+=f[i+j];
}
int main(){
#ifdef Stargazer
freopen("lx.in","r",stdin);
#endif
n=read(),m=1<<n;
for(int i=1;i<m;i++)cnt[i]=cnt[i>>1]+(i&1);
for(int i=0;i<n;i++){
readstring(str);
for(int j=1;j<=n;j++)if(str[j]=='1'){
e[i].pb(j-1);
}
}
for(int i=0;i<n;i++)dp[1<<i][i]=1;
for(int i=1;i<m;i++){
ll res=0;
for(int j=0;j<n;j++)if(i&(1<<j)){
ll now=dp[i][j];
for(int &k:e[j])if(!(i&(1<<k))){
dp[i+(1<<k)][k]+=now;
}
res+=dp[i][j];
}
f[cnt[i]][i]=res;
}
for(int i=1;i<=n;i++)fmt(f[i],m);
for(int i=0;i<m/2;i++){
vector<int> pt;int p=0;
while(p<n){
int len=1;
while(i&(1<<p)){
len++,p++;
}
pt.pb(len),p++;
}
sort(pt.bg(),pt.end());
sta[pt].pb(i);
}
for(int i=0;i<m;i++)val[i]=1;
dfs(0,1);
for(int mid=1;mid<m;mid<<=1)
for(int i=0;i<m/2;i+=mid<<1)
for(int j=0;j<mid;j++)
ans[i+j]-=ans[i+j+mid];
for(int i=0;i<m/2;i++)cout<<ans[i]<<" ";
return 0;
}
G
不会告辞
咕咕咕