发烧在家躺了一个星期呢…
直接判一下是不是有两对相等的
倒过来贪心,每次选最大的能选的
分三种情况讨论就完了,在一个串呢,在两个串呢,跨越n-2个串
先随便分一下,然后枚举小的集合的一个数,把它放到大的集合里,然后判断能不能分匀……感觉是能叉掉的
直接DP就好了
整体二分,把所有操作和怪兽编号取反,这样就能枚举怪兽的子集来找攻击到它的操作
复杂度很不科学…大概是 O(17×317) ,然后就跑过去了??
Manchery大佬说有trick能降复杂度,挖个坑
%%%rxdoi
把字符串分两段,设前一段的以0结尾的10子序列个数为f0,同样定义f1
后一段以0开始的10子序列个数为g0,同样定义g1
那么 x=f0g1+f1g0 ,化一下得到 g1=x−f1g0f0
枚举所有可行的g0,然后查一下表就好了…
这样枚举数就不容易被卡了,也可能就是很小??
#include
#include
#include
#include
#include
#include
using namespace std;
typedef unsigned int U;
typedef pair<int,int> par;
char a[40];
int t,n,cnt,cou[1<<16|10];
mapint > M;
int v[1<<16|10];
inline int count(U S){
return cou[S>>16]+cou[S&65535];
}
int gcd(int x,int y){
return y?gcd(y,x%y):x;
}
int main(){
scanf("%d",&t);
for(int i=1;i<(1<<16);i++) cou[i]=cou[i>>1]+(i&1);
while(t--){
M.clear(); cnt=0; int x,ans=33; U S=0;
scanf("%s%d",a+1,&x); n=strlen(a+1); x++;
int m1=n/2,m2=n-m1;
for(int i=1;i<=n;i++) S=S*2+a[i]-'0';
for(int i=0;i<(1<if(i&1) continue;
int g0=1,g1=0;
for(int j=1;jif(i>>j&1) g1+=g0; else g0+=g1+1;
g1++;
if(!M.count(par(g0,g1)))
M[par(g0,g1)]=count(i^(S&((1<1)));
else
M[par(g0,g1)]=min(M[par(g0,g1)],count(i^(S&((1<1))));
}
for(int i=0;i<(1<if(!(i>>(m1-1)&1)) continue;
int f1=1,f0=0;
for(int j=m1-2;~j;j--)
if(i>>j&1) f1+=f0+1; else f0+=f1;
f0++;
for(int g1=0;g1*f0<=x;g1++){
if((x-g1*f0)%f1) continue;
int g0,d=f1/gcd(f1,f0);
while(1LL*g1*f0<=x){
g0=(x-g1*f0)/f1;
if(M.count(par(g0,g1)))
ans=min(ans,M[par(g0,g1)]+count(i^(S>>m2)));
g1+=d;
}
}
}
if(ans>32) puts("NO");
else printf("YES\n%d\n",ans);
}
return 0;
}
为了这题重新学了一遍后缀自动机,感觉之前都白学了
建出后缀树(我使用后缀自动机建的)
那么每个节点就是一些子串的集合,那么子串大小排序就相当于后缀树的dfs序
在dfs序上二分就可以了
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int N=500010;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &x){
char c=nc(); x=0;
for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
inline void read(ll &x){
char c=nc(); x=0;
for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
inline void read(char *x){
char c=nc(); int l=0;
for(;c>'z'||c<'a';c=nc());for(;c>='a'&&c<='z';x[++l]=c,c=nc());
}
int n,q;
char a[N];
namespace SAM{
int p,cnt,nxt[N][26],fail[N],len[N],pos[N],val[N];
inline void extend(int x,int ps){
x-='a'; int np=++cnt; pos[np]=ps;
len[np]=len[p]+1; val[np]=1;
while(p && !nxt[p][x]) nxt[p][x]=np,p=fail[p];
if(!p) fail[np]=1;
else{
int q=nxt[p][x];
if(len[q]==len[p]+1) fail[np]=q;
else{
int nq=++cnt; len[nq]=len[p]+1;
memcpy(nxt[nq],nxt[q],sizeof(nxt[q]));
fail[nq]=fail[q]; fail[q]=fail[np]=nq; pos[nq]=pos[q];
while(p && nxt[p][x]==q) nxt[p][x]=nq,p=fail[p];
}
}
p=np;
}
int t[N],id[N];
inline void Pre(){
for(int i=1;i<=cnt;i++) t[len[i]]++;
for(int i=1;i<=cnt;i++) t[i]+=t[i-1];
for(int i=1;i<=cnt;i++) id[t[len[i]]--]=i;
for(int i=cnt;i;i--)
val[fail[id[i]]]+=val[id[i]];
}
}
namespace ST{
int nxt[N][26],val[N],len[N],pos[N],fa[N];
int lst[N],t;
ll pre[N];
void dfs(int x){
for(int i=0;i<26;i++)
if(nxt[x][i]){
lst[++t]=nxt[x][i];
dfs(nxt[x][i]);
}
}
inline ll calc(int A,int B){
return 1LL*(A+B)*(B-A+1)/2;
}
void Pre(){
dfs(1);
for(int p=1;p<=t;p++){
int i=lst[p];
pre[p]=pre[p-1]+calc(len[fa[i]]+1,len[i])*val[i];
}
}
inline char Query(ll x){
int l=1,r=t,mid,res=1;
while(l<=r) pre[mid=l+r>>1]1:r=(res=mid)-1;
x-=pre[res-1]; res=lst[res];
int L=len[fa[res]]+1,R=len[res],ret=len[fa[res]]+1;
while(L<=R) calc(len[fa[res]]+1,mid=(L+R>>1))*val[res]1:R=(ret=mid)-1;
if(ret>len[fa[res]]+1) x-=calc(len[fa[res]]+1,ret-1)*val[res]; x=(x-1)%ret+1;
return a[pos[res]+x-1];
}
}
inline void Build(){
using namespace SAM;
for(int i=2;i<=cnt;i++){
ST::pos[i]=pos[i];
ST::len[i]=len[i];
ST::val[i]=val[i];
ST::fa[i]=fail[i];
ST::nxt[fail[i]][a[pos[i]+len[fail[i]]]-'a']=i;
}
}
inline ll mul(ll x,ll y,ll P){
ll ret=0; x%=P; y%=P;
for(;y;y>>=1,x=(x+x)%P) if(y&1) ret=(ret+x)%P;
return ret;
}
int main(){
read(a); n=strlen(a+1);
SAM::cnt=SAM::p=1;
for(int i=n;i;i--) SAM::extend(a[i],i);
SAM::Pre(); Build(); ST::Pre();
ll lst=0;
read(q);
ll Q,M;
while(q--){
read(Q); read(M);
Q=mul(Q,lst,M)+1;
char c=ST::Query(Q);
putchar(c); putchar('\n');
lst+=c;
}
return 0;
}
二分加杜教筛…瞎卡常加上CC随机评测的机制就这样卡过去了…
代码不贴了,丑