题目链接:https://codeforces.com/contest/1186
A. Vus the Cossack and a Contest(600)
此题不会
B. NULL
此题没了
C. Vus the Cossack and Strings(1800)
题意:给定01串a与b,保证b的长度不大于a,求a中与b等长的所有连续子串中与b不同的位数为偶数的子串个数,即
解析:由于a和b都为01串,则当其相同数字个数之差为偶数时,无论如何排列,其不同的位数恒为偶数(不同排列可以看作多次交换,交换一次只能改变两个位置的数,由(n+2k)&1==n1得到结论)。
#include<bits/stdc++.h>
using namespace std;
int sum[1000010],d,ans;
string a,b;
int main()
{
ios::sync_with_stdio(false);
cin>>a>>b;
for(int i=1;i<=a.size();i++){sum[i]=sum[i-1]+a[i-1]-'0';}
for(int i=0;i<b.size();i++)d+=b[i]-'0';
for(int i=b.size();i<=a.size();i++)ans+=((sum[i]-sum[i-b.size()])%2==d%2);
cout<<ans;
}
D. Vus the Cossack and Numbers(1600)
题意:给定n个实数a1,a2…ai,我们对每个数都可以进行向上取整或向下取整的操作。现在,要使所有数操作之后的结果之和为零(题目保证结果存在),求出操作后的数列。
解析:既然题目保证有解,我们就可以使用贪心的思想,先将所有数都向下取整后求出和为S,然后遍历整个数组,每向上取整一次就等价于S++(此处要注意S为整数的情况),当S为零时结束,输出结果。
#include<bits/stdc++.h>
int n;
double a[100010],s=0;
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%lf",&a[i]),s+=(int)(a[i]<0&&a[i]!=(int)a[i]?(a[i]-1):a[i]);
for(int i=0;i<n;i++)
{
if(a[i]==(int)a[i]){printf("%d\n",(int)a[i]);continue;}
if(s)
{
if(a[i]<0)printf("%d\n",(int)a[i]),s++;
else printf("%d\n",(int)(a[i]+1)),s++;
}
else printf("%d\n",(int)(a[i]<0?(a[i]-1):a[i]));
}
}
E. Vus the Cossack and a Field(2500)
题意:给定大小为n*m的01矩阵M和变换S:
对M进行无限次变换S后。给出q个询问,每个询问包含四个数x1、y1、x2、y2,分别是矩阵左上角和右下角的坐标。对于每次询问,求出所问矩形中的所有元素之和。
解析:首先,根据变换S不难得出,
+
=
,也就是说,我们可以通过以下公式预处理出进行一次变换后的2n*2m矩阵的二维前缀和,即
(其实就是容斥定理,由此可以类比出k维前缀和的公式(呜呜呜不会画图)。)
同样利用前缀和的思想,我们可以把从
到
的和转化为
对于每个
,考虑其和2n*2m的数量关系,经过稍微麻烦的的分类讨论就能做出来啦~
(看了橙名大佬lintoto的大佬的ac代码,学到了一些神奇的预处理和位运算的方法,%%%)
(还是因为爆longlong而wa了好几发QAQ)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2010;
int n,m,Q,s[N][N];
char str[N];
ll calc(ll x,ll y)
{
ll ret=(x*y-(x%n)*(y%m))/2;
ll t=(x/n)^(y/m),num=0;
while(t)num+=t&1,t>>=1;
if(num&1)ret+=(x%n)*(y%m)-s[x%n][y%m];else ret+=s[x%n][y%m];
return ret;
}
int main()
{
scanf("%d%d%d",&n,&m,&Q);
for(int i=1;i<=n;i++)
{
scanf("%s",str+1);
for(int j=1;j<=m;j++)s[i][j]=s[i+n][j+m]=str[j]-'0',s[i+n][j]=s[i][j+m]=s[i][j]^1;
}
n<<=1,m<<=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
s[i][j]+=s[i-1][j]+s[i][j-1]-s[i-1][j-1];
while(Q--)
{
ll a,b,c,d;scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
printf("%lld\n",calc(c,d)+calc(a-1,b-1)-calc(a-1,d)-calc(c,b-1));
}
}
F. Vus the Cossack and a Graph(2300)
题意:咕咕咕