A. Protect Sheep
As long as there is no sheep in wolf's four adjacent lattices, there must be a way to let the dog keep the wolf out of contact with the sheep, and replace all the spaces with dogs.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=505;
const int maxm=100005;
const int maxe=200005;
const int mod=1e9+7;
int n,m;
char ma[maxn][maxn];
int dx[4]={-1,0,0,1};
int dy[4]={0,-1,1,0};
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%s",ma[i]);
}
bool f=1;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(ma[i][j]=='W'){
for(int k=0;k<4;k++){
int nx=i+dx[k];
int ny=j+dy[k];
if(nx<0||nx>=n)continue;
if(ny<0||ny>=m)continue;
if(ma[nx][ny]=='S'){f=0;break;}
}
}
if(f==0)break;
}
if(f==0)break;
}
if(f==0){printf("No\n");return 0;}
printf("Yes\n");
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(ma[i][j]=='.')ma[i][j]='D';
}
}
for(int i=0;i<n;i++){
printf("%s\n",ma[i]);
}
return 0;
}
B. Primal Sport
First, all prime numbers are processed.
The idea is to first find out what the minimum value of X0 is when each number is X1, and then to determine the range of the value of X1 by traversing every prime factor of x2, and then to find the minimum value of the answer by traversing that range of values.
1. The method to determine the minimum value of x0 corresponding to each x1 is to update its multiples a=k*prime (k > 2), x0[a]=min(x0[a],prime*(k-1)+1) with each prime number.
2. The final value range of x 1 must be a continuous interval (k to n). The method of determining the range is similar to (1)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1000005;
const int maxm=100005;
const int maxe=200005;
const int mod=1e9+7;
int n,m;
int prime[maxn];
int tot;
bool vis[maxn];
void init(){
tot=0;
for(int i=2;i<maxn;i++){
if(vis[i])continue;
prime[tot++]=i;
for(int j=2;j*i<=maxn;j++){
vis[j*i]=1;
}
}
}
int pre[maxn];
int main(){
init();
scanf("%d",&n);
memset(pre,0x3f,sizeof(pre));
for(int i=0;i<tot;i++){
int num=prime[i];
for(int j=2;j*num<=n;j++){
pre[j*num]=min(pre[j*num],(j-1)*num+1);
}
}
int ans=0x3f3f3f3f;
int cnt=n;
for(int i=tot-1;i>=0;i--){
if(prime[i]>=n)continue;
if(n%prime[i])continue;
int pos=((n/prime[i])-1)*prime[i]+1;
while(cnt>=pos){
ans=min(ans,pre[cnt]);
cnt--;
}
}
printf("%d\n",ans);
return 0;
}
C. Producing Snow
Considering the contribution of new snow to the amount of melting in the next day, i t is found that if the snow on day I melts on day k, its contribution to day I to day K is t[j], and the contribution to day K is the amount of remaining snow.
So the dichotomous snow melts just the next day, and then marks the interval in a way similar to the prefix sum.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=101005;
const int maxm=100005;
const int maxe=200005;
const int mod=1e9+7;
int n,m;
ll v[maxn];
ll t[maxn];
ll sum[maxn];
ll a[maxn];
ll ans[maxn];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lld",&v[i]);
for(int i=1;i<=n;i++)scanf("%lld",&t[i]);
for(int i=1;i<=n;i++){
sum[i]=sum[i-1]+t[i];
}
for(int i=1;i<=n;i++){
int pos=lower_bound(sum+i,sum+n+1,v[i]+sum[i-1])-sum;
ans[pos]+=v[i]+sum[i-1]-sum[pos-1];
a[i]++;
a[pos]--;
}
for(int i=1;i<=n;i++){
a[i]+=a[i-1];
ans[i]+=a[i]*t[i];
}
for(int i=1;i<=n;i++){
printf("%lld ",ans[i]);
}
return 0;
}
D. Perfect Security
One point of violence is the practice of the n side, which must be overtime.
XOR can be considered bit by bit. If every number wants XOR, it will become smaller. It must be XOR or a binary bit is the most similar and the number of different bits is as small as possible and as low as possible. Therefore, building a dictionary tree can be used to query. It is enough to insert each number into a 30-bit binary string into trie, involving deletion operation and opening an array of counts.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MP make_pair
const int maxn=300005;
const int maxm=(1<<25);
int n,m;
int a[maxn],p[maxn];
int ch[maxm][2];
int cou[maxm];
int sz;
void inser(int num){
int u=0;
for(int i=30;i>=0;i--){
int c=0;
if((1<<i)&num)c=1;
if(!ch[u][c]){
ch[sz][0]=ch[sz][1]=0;
cou[sz]=0;
ch[u][c]=sz++;
}
cou[u]++;
u=ch[u][c];
}
cou[u]++;
}
void build(){
for(int i=0;i<n;i++){
inser(p[i]);
}
}
int cal(int num){
int num1=num;
int u=0;
for(int i=30;i>=0;i--){
int c=0;
if((1<<i)&num)c=1;
if(!ch[u][c]||!cou[ch[u][c]]){
c=1-c;
}
num1^=(c<<i);
cou[u]--;
u=ch[u][c];
}
cou[u]--;
return num1;
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
for(int i=0;i<n;i++)scanf("%d",&p[i]);
sz=1;
memset(ch[0],0,sizeof(ch[0]));
build();
for(int i=0;i<n;i++){
printf("%d ",cal(a[i]));
}
return 0;
}
E. Picking Strings
Push a few formulas to find:
B can be changed into C, so C in both strings is treated as B.
Any number of A can be added before any B, so the non-terminal A of the query interval can be ignored.
The number of B can not be reduced by increasing itself, and can only be increased even times.
A at the end of the interval can only be directly reduced by three or one A to two B or two A to two B.
So count the number of prefixes in B and the length of suffixes in A, and then discuss them in categories.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MP make_pair
const int maxn=100005;
const int maxm=(1<<25);
int n,m;
char s[maxn],t[maxn];
int bn1[maxn],bn2[maxn];
int an1[maxn],an2[maxn];
int a,b,c,d;
int main(){
scanf("%s%s",s+1,t+1);
n=strlen(s+1),m=strlen(t+1);
for(int i=1;i<=n;i++){
bn1[i]+=bn1[i-1]+(s[i]!='A'?1:0);
if(s[i]!='A')continue;
an1[i]=1+an1[i-1];
}
for(int i=1;i<=m;i++){
bn2[i]+=bn2[i-1]+(t[i]!='A'?1:0);
if(t[i]!='A')continue;
an2[i]=1+an2[i-1];
}
int Q;
scanf("%d",&Q);
while(Q--){
scanf("%d%d%d%d",&a,&b,&c,&d);
int b1num=bn1[b]-bn1[a-1];
int a1num=min(b-a+1,an1[b]);
int b2num=bn2[d]-bn2[c-1];
int a2num=min(d-c+1,an2[d]);
if(b1num>b2num){putchar('0');continue;}
if(b1num==b2num){
if(a1num<a2num){putchar('0');continue;}
int cha=a1num-a2num;
if(cha%3){putchar('0');}
else putchar('1');
continue;
}
if(b1num==0){
if(b2num%2){putchar('0');continue;}
if(a1num<=a2num){putchar('0');continue;}
int lef=(a1num-a2num)%3;
if(lef>b2num){putchar('0');continue;}
putchar('1');
continue;
}
if(b1num<b2num){
int cha=b2num-b1num;
if(cha%2){putchar('0');continue;}
if(a1num<a2num){putchar('0');continue;}
int lef=(a1num-a2num)%3;
if(b1num+lef>b2num){putchar('0');continue;}
putchar('1');
continue;
}
}
return 0;
}