codeforce
emmmmmm,受最近集训的影响,看啥都像二分+前缀和…然后超时了(然后改了几个字就A了,我应该哭还是笑呢?
B. Letters Shop
题解:
血泪教训:(还好我没打比赛不然亏死)
不要用strlen,不要用strlen,超慢 超慢 超慢,
字符串最好使用string,唉一上午的debug啊…
版本一:
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<set>
#include<map>
#include<iterator>
#include<queue>
#include<vector>
#include<string>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const long long INF=1e18;
const double eps=0.0000001;
const ll mod=1e9+7;
int sn[26];
vector<int>ans[26];
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int t,n;
string str,stl;
cin>>t;
cin>>str;
for(int i=0;i<t;i++)
{
ans[str[i]-'a'].push_back(i);
}
cin>>n;
int mx;
while(n--)
{
memset(sn,0,sizeof(sn));
cin>>stl;
mx=0;
for(int i=0;i<stl.length();i++)
sn[stl[i]-'a']++;
for(int i=0;i<26;i++)
{
if(sn[i]!=0)
mx=max(ans[i][sn[i]-1]+1,mx);
}
printf("%d\n",mx);
}
}
版本二:
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<set>
#include<map>
#include<iterator>
#include<queue>
#include<vector>
#include<string>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const long long INF=1e18;
const double eps=0.0000001;
const ll mod=1e9+7;
string stl,str;
int num[N][26];
int num2[N][26];
int slove(int x,int k)
{
int flag=0;
for(int j=0;j<26;j++)
{
if(num[x][j]<num2[k][j])
{
flag=1;
break;
}
}
if(flag==0)
return 1;
return 0;
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int t,n;
cin>>t;
cin>>str;
for(int i=0;i<t;i++)
{
for(int j=0;j<26;j++)
{
if(i!=0)
num[i][j]=num[i-1][j];
}
num[i][str[i]-'a']++;
}
cin>>n;
for(int j=0;j<n;j++)
{
cin>>stl;
for(int i=0;i<stl.length();i++)//超时原因:不要用strlen
{
num2[j][stl[i]-'a']++;
}
}
for(int k=0;k<n;k++)
{
int l=0,r=t-1,mid,ans;
while(l<=r)
{
mid=(l+r)>>1;
if(slove(mid,k))
{
ans=mid;
r=mid-1;
}
else
l=mid+1;
}
cout<<(ans+1)<<endl;;
}
}
原本打算补一下C,D。加再做一套CF。然后做分块8自闭了…
C. Vasya And Array
题意:
就是构造一个长度为
n
n
n的数组,然后给出
m
m
m条描述条件,分为两种描述,一种是描述区间
[
l
,
r
]
[l,r]
[l,r]内的数非递减,另一种描述
[
l
,
r
]
[l,r]
[l,r]内的数不是非递减
题解:
找到临界的状态,如果连这个状态都不满足,那么肯定不存在这样一个状态
写题的时候细点心吧,不然debug好久…
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<set>
#include<map>
#include<iterator>
#include<queue>
#include<vector>
#include<string>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const long long INF=1e18;
const double eps=0.0000001;
const ll mod=1e9+7;
int vis[N];
int sum[N];
vector<pair<int,int> >ans;
int slove(int l,int r)
{
for(int i=l+1;i<=r;i++)
{
if(sum[i-1]>sum[i])
return 0;
}
return 1;
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n,m,ty,l,r;
cin>>n>>m;
for(int i=0;i<m;i++)
{
cin>>ty>>l>>r;
if(ty)
{
vis[l]++;
vis[r]--;
}
else
{
ans.push_back({l,r});
}
}
for(int i=1;i<=n;i++)
{
vis[i]+=vis[i-1];
}
int flag=n+1;
for(int i=1;i<=n;i++)
{
if(vis[i]&&vis[i-1]||vis[i-1]&&!vis[i])
{
sum[i]=flag;
}
else if(!vis[i-1]&&vis[i]||!vis[i]&&!vis[i-1])
{
flag--;
sum[i]=flag;
}
}
for(int i=0;i<ans.size();i++)
{
if(slove(ans[i].first,ans[i].second))
{
cout<<"NO"<<endl;
return 0;
}
}
cout<<"YES"<<endl;
for(int i=1;i<=n;i++)
{
cout<<sum[i]<<" ";
}
}
7.2号摸鱼了…反省五分钟
Codeforces Round #571 (Div. 2),
C. Vus the Cossack and Strings
题意:
给定两个由
0
,
1
0,1
0,1构成的字符串
a
a
a和
b
b
b,其中
∣
b
∣
≤
∣
a
∣
.
|b|\leq |a|.
∣b∣≤∣a∣.
对于 a a a的某个长度为 ∣ b ∣ |b| ∣b∣的字串 c c c,记对应位不同的字符数为 f ( b , c ) . f(b, c). f(b,c).
如:当 b = 00110 , c = 11000 b=00110,c=11000 b=00110,c=11000时, f ( b , c ) = 4 , f(b, c) = 4, f(b,c)=4,,其中第 1 , 2 , 3 , 4 1,2,3,4 1,2,3,4位不同。
求所有
c
c
c中
f
(
b
,
c
)
f(b,c)
f(b,c)为偶数的个数
题解:
主要是能找到规律,否则就很麻烦
规律:如果两个字符串的字符‘1’的数目的奇偶性相同,那么两个字符串不同的位置数一定为偶数。
然后用前缀和来维护一段区间上的‘1’的数目就可以了
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<set>
#include<map>
#include<iterator>
#include<queue>
#include<vector>
#include<string>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const long long INF=1e18;
const double eps=0.0000001;
const ll mod=1e9+7;
int vis[N];
int sum;
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n,m,ty,l,r,k;
string s1,s2;
cin>>s1>>s2;
s1=" "+s1;
s2=" "+s2;
int len1=s1.length()-1;
int len2=s2.length()-1;
for(int i=1;i<=len2;i++) if(s2[i]=='1') sum++;
for(int i=1;i<=len1;i++) vis[i]=vis[i-1]+(s1[i]=='1');
int ans=0;
for(int i=1;i<=len1-len2+1;i++)
{
if((vis[i+len2-1]-vis[i-1])%2==sum%2)
ans++;
}
cout<<ans<<endl;
}