省選模擬(zero4338)
阿新 • • 發佈:2022-02-22
似乎又是挺簡單的一場??戰神的良心題!!
考場上完全沒有思考第一題的性質,導致啥也不會到九點
第二題看完之後認為是dp套dp後來發現可以爆搜
第三題似乎是暴力hash就行,也是找性質題
主要是自己的思維量不夠,啥性質也找不到。。。
T1 End Sky II
如果想要判斷一個數x是否可行,就是判斷所有\(a[i]&x==x\)的數能否將整個序列分成k段並且作為這k段的最大值出現
我們先不考慮判斷的方法,如果我們可以判斷了,那麼就直接按位確定就行了
發現如果區間數量多於k,那麼直接合並兩個區間答案只會大不會小
所以實際上我們找的就是最大區間劃分數,可以用線段樹暴力做,也可以根據每一個數是劃分到自己這裡,還是前一個合法的或者後一個合法的
AC_code
#include<bits/stdc++.h> using namespace std; #define fo(i,x,y) for(int i=(x);i<=(y);i++) #define fu(i,x,y) for(int i=(x);i>=(y);i--) int read(){ int s=0,t=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();} while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();} return s*t; } const int N=2e5+5; int n,k,a[N],ans; int ml[N],mr[N],sta[N],top; int pre[N],nxt[N],f[N]; bool check(int x){ memset(f,-0x3f,sizeof(f));f[0]=0; fo(i,1,n){ if((a[i]&x)==x)pre[i]=i;//cerr<<i<<" "; else pre[i]=pre[ml[i]]; } fu(i,n,1){ if((a[i]&x)==x)nxt[i]=i; else nxt[i]=nxt[mr[i]]; } fo(i,1,n){ if((a[i]&x)==x)f[i]=max(f[i],f[i-1]+1); else { if(pre[i])f[i]=max(f[i],f[pre[i]]); if(nxt[i])f[nxt[i]]=max(f[nxt[i]],f[i-1]+1); } } //cerr<<x<<endl; return f[n]>=k; } signed main(){ freopen("sky.in","r",stdin); freopen("sky.out","w",stdout); n=read();k=read(); fo(i,1,n){ a[i]=read(); while(a[sta[top]]<a[i]&&top)mr[sta[top--]]=i; sta[++top]=i; }while(top)mr[sta[top--]]=n+1; fu(i,n,1){ while(a[sta[top]]<a[i]&&top)ml[sta[top--]]=i; sta[++top]=i; }while(top)ml[sta[top--]]=0; //fo(i,1,n)cerr<<ml[i]<<" "<<mr[i]<<endl; fu(i,30,0)if(check(ans|(1<<i)))ans|=(1<<i); printf("%d",ans); }
T2 Hill of Sunflowers
直接搜,咋搜都行!!!
有一個重要的就是如果有一個遞增序列,每一個數的取值範圍也是遞增的
如果範圍比較小的話,那麼我們列舉每一個數的取值在哪個範圍就好了!!
AC_code
#include<bits/stdc++.h> using namespace std; #define int long long #define fo(i,x,y) for(int i=(x);i<=(y);i++) #define fu(i,x,y) for(int i=(x);i>=(y);i--) int read(){ int s=0,t=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();} while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();} return s*t; } const int N=10; const int mod=1e9+7; int ksm(int x,int y){ int ret=1; while(y){ if(y&1)ret=ret*x%mod; x=x*x%mod;y>>=1; }return ret; } int n,a[N],ans; int su[N],so[N],xl[N],b[N],fas; bool com(int x,int y){return so[x]!=so[y]?so[x]<so[y]:a[x]>a[y];} map<int,int> mp;int ys[N]; int C(int x,int y){ if(x<y)return 0; int ret=1; fo(i,x-y+1,x)ret=ret*i%mod; fo(i,1,y)ret=ret*ksm(i,mod-2)%mod; return ret; } int ji[N],nn; void dfs_fas(int x){ if(x==nn+1){ int las=1,res=1; fo(i,1,nn)if(ji[i]!=ji[i-1]){res=res*C(ji[i-1]-ji[las-1],i-las)%mod;las=i;} //cout<<res<<" "<<las<<" "<<ji[1]<<" "<<ji[2]<<" "<<ji[3]<<" "; res=res*C(ji[nn]-ji[las-1],nn-las+1)%mod; fas=(fas+res)%mod;//cout<<res<<endl; return ; } if(x>1){ji[x]=ji[x-1];dfs_fas(x+1);} ji[x]=b[x];dfs_fas(x+1); } int f[N],fmx,sum; bool vis[1<<20]; int lsh[N],lh; void dfs_sort(int x){ if(x==n+1){ int now=0;lh=0; fo(i,1,n)lsh[++lh]=su[i];//cout<<so[i]<<" ";cout<<"T"<<" "; sort(lsh+1,lsh+lh+1); lh=unique(lsh+1,lsh+lh+1)-lsh-1; fo(i,1,n)so[i]=lower_bound(lsh+1,lsh+lh+1,su[i])-lsh;//cout<<so[i]<<" ";cout<<endl; now=so[1];fo(i,2,n)now=(now<<3)+so[i]; if(vis[now])return ;vis[now]=true;//cout<<now<<" "; fo(i,1,n)xl[i]=i; sort(xl+1,xl+n+1,com); //fo(i,1,n)cout<<xl[i]<<" "<<a[xl[i]]<<endl; b[n]=a[xl[n]];fu(i,n-1,1){ if(so[xl[i]]==so[xl[i+1]])b[i]=min(a[xl[i]],b[i+1]); else b[i]=min(a[xl[i]],b[i+1]-1); //if(b[i]<=0)return ; } //fo(i,1,n)cout<<xl[i]<<" "<<b[i]<<" "<<so[xl[i]]<<endl;cout<<"S"<<endl; nn=0;fo(i,1,n)if(so[xl[i]]!=so[xl[i-1]])b[++nn]=b[i]; //fo(i,1,nn)cout<<xl[i]<<" "<<b[i]<<endl; //int cnt=0;mp.clear(); //fo(i,1,n)if(mp.find(b[i])==mp.end())mp[b[i]]=++cnt,ys[cnt]=b[i]; fas=0;dfs_fas(1); memset(f,0,sizeof(f));fmx=0; fo(i,1,n){ f[i]=1; fo(j,1,i-1)if(so[j]<so[i])f[i]=max(f[i],f[j]+1); fmx=max(fmx,f[i]); } //cout<<"fas"<<" "<<fas<<" "<<fmx<<endl; ans=(ans+fas*fmx)%mod;sum=(sum+fas)%mod; return ; } fo(i,1,n)su[x]=i,dfs_sort(x+1); } int anss; void dfs(int x){ if(x==n+1){ memset(f,0,sizeof(f));fmx=0; fo(i,1,n){ f[i]=1; fo(j,1,i-1)if(so[j]<so[i])f[i]=max(f[i],f[j]+1); fmx=max(fmx,f[i]); }anss=(anss+fmx)%mod; return ; } fo(i,1,a[x])so[x]=i,dfs(x+1); } signed main(){ freopen("hill.in","r",stdin); freopen("hill.out","w",stdout); n=read(); fo(i,1,n)a[i]=read(); //dfs(1);cout<<anss<<endl; dfs_sort(1);//cout<<sum<<" "<<ans<<endl; fo(i,1,n)ans=ans*ksm(a[i],mod-2)%mod; printf("%lld",ans); return 0; }
T3 Wonderful Everyday
兩個數相加等於一個數,要麼是某一個數和答案一樣長,另一個數是答案長度減lcp或者再減1
要麼是兩個數長度都是答案長度減一
暴力hash判斷就行了,多換幾個模數!!
AC_code
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
return s*t;
}
const int N=2e5+5;
const ull bas=10;
const ll mod=1000000007;
const ll mob=998244353;
const ll moa=998244354;
char chs[N],cht[N];int pp[N*2],lp;
int ls,lt,ss[N],st[N],z[N*2];
ull ba[N],hs[N],ht[N];
ll ca[N],cs[N],ct[N];
ll da[N],ds[N],dt[N];
ll aa[N],as[N],at[N];
bool ck(int l1,int r1,int l2,int r2){
return ((hs[r1]-hs[l1-1]*ba[r1-l1+1]+hs[r2]-hs[l2-1]*ba[r2-l2+1]==ht[lt])&&
((cs[r1]-cs[l1-1]*ca[r1-l1+1]%mod+mod+cs[r2]-cs[l2-1]*ca[r2-l2+1]%mod+mod)%mod==ct[lt])&&
((ds[r1]-ds[l1-1]*da[r1-l1+1]%mob+mob+ds[r2]-ds[l2-1]*da[r2-l2+1]%mob+mob)%mob==dt[lt])&&
((as[r1]-as[l1-1]*aa[r1-l1+1]%moa+moa+as[r2]-as[l2-1]*aa[r2-l2+1]%moa+moa)%moa==at[lt]));
}
signed main(){
freopen("wonderful.in","r",stdin);
freopen("wonderful.out","w",stdout);
scanf("%s%s",chs+1,cht+1);
ls=strlen(chs+1);lt=strlen(cht+1);
fo(i,1,ls)ss[i]=chs[i]-'0';
fo(i,1,lt)st[i]=cht[i]-'0';
ba[0]=1;fo(i,1,ls)ba[i]=ba[i-1]*bas;
fo(i,1,ls)hs[i]=hs[i-1]*bas+ss[i];
fo(i,1,lt)ht[i]=ht[i-1]*bas+st[i];
ca[0]=1;fo(i,1,ls)ca[i]=ca[i-1]*bas%mod;
fo(i,1,ls)cs[i]=(cs[i-1]*bas%mod+ss[i])%mod;
fo(i,1,lt)ct[i]=(ct[i-1]*bas%mod+st[i])%mod;
da[0]=1;fo(i,1,ls)da[i]=da[i-1]*bas%mob;
fo(i,1,ls)ds[i]=(ds[i-1]*bas%mob+ss[i])%mob;
fo(i,1,lt)dt[i]=(dt[i-1]*bas%mob+st[i])%mob;
aa[0]=1;fo(i,1,ls)aa[i]=aa[i-1]*bas%moa;
fo(i,1,ls)as[i]=(as[i-1]*bas%moa+ss[i])%moa;
fo(i,1,lt)at[i]=(at[i-1]*bas%moa+st[i])%moa;
fo(i,1,lt)pp[++lp]=st[i];
fo(i,1,ls)pp[++lp]=ss[i];
z[1]=lp;
for(int i=2,mx=0,id=0;i<=lp;i++){
if(i<=mx)z[i]=min(z[i-id+1],mx-i+1);
while(i+z[i]<=lp&&pp[i+z[i]]==pp[1+z[i]])z[i]++;
if(i+z[i]-1>mx)mx=i+z[i]-1,id=i;
}
cerr<<lt<<endl;
fo(l1,1,ls){
int r2;
if(l1+lt+lt-1-z[l1+lt]<=ls&&z[l1+lt]!=lt){
if(ck(l1,l1+lt-1,l1+lt,r2=l1+lt+lt-1-z[l1+lt])){
printf("%d %d\n%d %d",l1,l1+lt-1,l1+lt,r2);
return 0;
}
}
if(l1+lt+lt-2-z[l1+lt]<=ls&&z[l1+lt]!=lt){
if(ck(l1,l1+lt-1,l1+lt,r2=l1+lt+lt-2-z[l1+lt])){
printf("%d %d\n%d %d",l1,l1+lt-1,l1+lt,r2);
return 0;
}
}
if((l1+lt-1+lt-1-1<=ls)&&(ck(l1,l1+lt-2,l1+lt-1,l1+lt-1+lt-1-1))){
cerr<<l1<<" "<<l1+lt-1<<" "<<l1+lt-1+lt-1-1<<endl;
printf("%d %d\n%d %d",l1,l1+lt-2,l1+lt-1,l1+lt-1+lt-1-1);
return 0;
}
}
fo(l2,1,ls){
if(lt-z[l2+lt]<l2&&z[l2+lt]!=lt){
if(ck(l2-1-(lt-z[l2+lt])+1,l2-1,l2,l2+lt-1)){
printf("%d %d\n%d %d",l2-1-(lt-z[l2+lt])+1,l2-1,l2,l2+lt-1);
}
}
if(lt-z[l2+lt]<=l2&&z[l2+lt]!=lt){
if(ck(l2-1-(lt-z[l2+lt]-1)+1,l2-1,l2,l2+lt-1)){
printf("%d %d\n%d %d",l2-1-(lt-z[l2+lt]-1)+1,l2-1,l2,l2+lt-1);
}
}
}
return 0;
}