2017 計蒜之道初賽第五場題解
阿新 • • 發佈:2019-02-13
A:水題,WA了三次。。。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int n,m;
while(cin>>n>>m)
{
vector<int> a(m);
for(auto &v:a) cin>>v;
sort(a.begin(),a.end(),[](int a,int b){ return a>b; });
int k=1,ans=0;
bool ok=false;
if(n>1)
for(int i=0;i<m&&a[i];i++)
{
k+=a[i]-1;
ans=i+1;
if(k>=n)
break;
}
if(k>=n) cout << ans << endl;
else cout << "Impossible" << endl;
}
return 0;
}
B,C:
類似XDOJ的1175。
動態維護s上一個長度為k的區間內不同數字的個數及其數量。
複雜度為
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=50007;
int s[N],t[N],tmp[N],n,m,c1[N],c2[N];
int main()
{
int T;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf ("%d",&s[i]);
scanf("%d",&T);
while(T--)
{
scanf("%d",&m);
for(int i=1;i<=m;i++) scanf("%d",&t[i]);
memset(c2,0,sizeof(c2));
memset(c1,0,sizeof(c1));
int ans=0,num=0,res=0;
for(int i=1;i<=m;i++)
{
if(!c2[t[i]]) ++num;
++c2[t[i]];
}
for(int i=1;i<=m;i++)
{
if(c1[s[i]]==c2[s[i]]) --res;
++c1[s[i]];
if(c1[s[i]]==c2[s[i]]) ++res;
}
if(res==num) ++ans;
for(int i=m+1;i<=n;i++)
{
if(c1[s[i]]==c2[s[i]]) --res;
++c1[s[i]];
if(c1[s[i]]==c2[s[i]]) ++res;
if(c1[s[i-m]]==c2[s[i-m]]) --res;
--c1[s[i-m]];
if(c1[s[i-m]]==c2[s[i-m]]) ++res;
if(res==num) ++ans;
}
printf("%d\n",ans);
}
return 0;
}
D:
考慮到
因此離線處理,先讀入所有的詢問,然後對於長度
判斷
維護
把雜湊表的複雜度看成
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=1e5+7,N=5e4+7;
const int mod=M;
typedef vector<int> vi;
vector<int> s,t[M];
vector<int> T[N];
int ans[M],vis1[N],vis2[N],vs=1,c1[N],c2[N];
int n,m,L;
vector<vi> ht[mod];
bool iseq(vi &a,vi &b,int l)
{
int cnt1=0,cnt2=0;
for(auto &c : a)
{
if(vis1[c]!=vs)
{
vis1[c]=vs;
c1[c]=1;
++cnt1;
}
else ++c1[c];
}
for(int i=0;i<a.size();i++)
{
int c=b[i+l];
if(vis2[c]!=vs)
{
vis2[c]=vs;
c2[c]=1;
}
else ++c2[c];
if(vis1[c]==vs)
{
if(c1[c]==c2[c]) ++cnt2;
else if(c1[c]==c2[c]-1) --cnt2;
}
}
++vs;
return cnt1==cnt2;
}
void update(int hv,int l)
{
for(auto &vec:ht[hv])
{
int j=vec[0];
if(iseq(t[j],s,l))
{
for(auto &v:vec)
++ans[v];
return ;
}
}
}
void insert(int id)
{
int hv=0;
for(int i=0;i<t[id].size();++i) hv=(hv+t[id][i])%mod;
vi v;
for(auto& vec:ht[hv])
{
int x=vec[0];
if(iseq(t[x],t[id],0))
{
vec.push_back(id);
return ;
}
}
v.push_back(id);
ht[hv].push_back(v);
}
int main()
{
scanf("%d",&n);
s=vector<int>(n);
for(int i=0;i<n;i++)
scanf("%d",&s[i]);
scanf("%d",&m);
for(int i=0;i<m;i++)
{
int k;
scanf("%d",&k);
t[i]=vector<int>(k);
for(int j=0;j<k;++j) scanf("%d",&t[i][j]);
T[t[i].size()].push_back(i);
}
for(int i=1;i<=n;++i)
{
if(!T[i].size()) continue;
for(int j=0;j<mod;++j) ht[j].clear();
for(auto j:T[i]) insert(j);
int hv=0;
L=t[T[i][0]].size();
for(int j=0;j<L;++j) hv=(hv+s[j])%mod;
update(hv,0);
for(int j=L;j<n;++j)
{
hv=(hv-s[j-L]+mod)%mod;
hv=(hv+s[j])%mod;
update(hv,j-L+1);
}
}
for(int i=0;i<m;i++)
printf("%d\n",ans[i]);
return 0;
}