cf984(div3)(A-G)
要复健了:(
A
void solve(){
int n;cin>>n;
vector<int>a(n+1);
rep(i,1,n){
cin>>a[i];
}
rep(i,2,n){
if(abs(a[i]-a[i-1])!=5&&abs(a[i]-a[i-1])!=7){
cout<<"NO"<<endl;return;
}
}
cout<<"YES"<<endl;
}
B
模拟+贪心,看哪一个品类的商品总价值最高就先卖哪一类
void solve(){
int n,k;cin>>n>>k;
map<int,int>tot;
rep(i,1,k){
int b,c;cin>>b>>c;
tot[b]+=c;
}
priority_queue<int>q;
for(auto[x,y]:tot){
q.push(y);
}
int ans=0;
while(n&&q.size()){
ans+=q.top();
q.pop();
n--;
}
cout<<ans<<endl;
}
C
题意:
给定一个01字符串以及q次查询,每次查询修改字符串一个位置的字符,求每次查询过后字符串是否存在1100子串
思路:
先计算原本的字符串的1100子串数目
每次查询中,如果修改后的字符与原字符相同,则相当于没修改
反之,需要观察这个字符影响的答案,即它会影响从max(1,i-3)~min(n-3,i)开头的长度为4的字符串
暴力判断即可
void solve(){
string s;cin>>s;
int n=s.size();
s=" "+s;
int cnt=0;
rep(i,1,n-3){
if(s.substr(i,4)=="1100"){
cnt++;
}
}
int q;cin>>q;
while(q--){
int i;cin>>i;char ch;cin>>ch;
if(s[i]!=ch){
for(int j=max(1,i-3);j<=min(n-3,i);j++){
if(s.substr(j,4)=="1100"){
cnt--;
}
}
s[i]=ch;
for(int j=max(1,i-3);j<=min(n-3,i);j++){
if(s.substr(j,4)=="1100"){
cnt++;
}
}
}
if(cnt>0){
cout<<"YES"<<endl;
}else cout<<"NO"<<endl;
}
}
D
题意:
给定一个nxm的数字矩阵,其中n和m都是偶数,求min(n,m)/2个绕着矩阵中心的大环上有多少个1543
思路:
需要暴力模拟
先看如何把矩阵的一个环给扯下来
显然如果是第i个环,那么
第i行:[i,m-i+1]列
第m-i+1列:[i+1,n-i+1]行
第n行:[m-i,i]列
第i列:[n-i,i+1]行
把环上的数字取下来放到数组里,然后取模判断1543的数量
环的数量为min(n,m)/2
char g[1005][1005];
int check(vector<char>&v){
int k=v.size();
int res=0;
for(int j=0;j<k;j++){
if(v[j]=='1'&&v[(j+1)%k]=='5'&&v[(j+2)%k]=='4'&&v[(j+3)%k]=='3')res++;
}
return res;
}
void solve(){
int n,m;cin>>n>>m;
rep(i,1,n){
string s;cin>>s;s=" "+s;
rep(j,1,m){
g[i][j]=s[j];
}
}
int ans=0;
for(int i=1;i<=min(n,m)/2;i++){
vector<char>v;
for(int j=i;j<=m+1-i;j++)v.pb(g[i][j]);
for(int j=i+1;j<=n+1-i;j++)v.pb(g[j][m+1-i]);
for(int j=m-i;j>=i;j--)v.pb(g[n-i+1][j]);
for(int j=n-i;j>=i+1;j--)v.pb(g[j][i]);
ans+=check(v);
}
cout<<ans<<endl;
}
E
题意:
给定一个nxk的矩阵,矩阵的每一列从第一行到第n行,变换为x|pre(x为所处位置的矩阵值,pre为上面行的矩阵按位或值)
给出m个条件限制每一列的大小,需要输出满足条件的最小行的编号
思路:
显然通过按位或操作后的矩阵,下面行的值一定大于等于上面行的值
每一列都满足从上至下单调递增,所以可以二分
划定满足答案的编号范围为l~r,初始l=1,r=n
对于每一个条件,二分调整l或r的大小
如果最后l>r那么无解
void solve(){
int n,k,q;cin>>n>>k>>q;
vector<vector<int>>g(n+1,vector<int>(k+1));
rep(i,1,n){
rep(j,1,k){
cin>>g[i][j];
}
}
for(int j=1;j<=k;j++){
int pre=0;
for(int i=1;i<=n;i++){
pre|=g[i][j];
g[i][j]=pre;
}
}
while(q--){
int m;cin>>m;
int l=1,r=n;
int f=1;
rep(i,1,m){
int rt,c;char o;
cin>>rt>>o>>c;
//g[1~n][r]
if(o=='>'){
int li=l,ri=r;
int ok=0;
while(li<=ri){
int mid=li+ri>>1;
if(g[mid][rt]>c){
l=mid;
ok=1;
ri=mid-1;
}else li=mid+1;
}
if(!ok)f=0;
}else if(o=='<'){
int li=l,ri=r;
int ok=0;
while(li<=ri){
int mid=li+ri>>1;
if(g[mid][rt]<c){
r=mid;
ok=1;
li=mid+1;
}else ri=mid-1;
}
if(!ok)f=0;
}
}
if(l<=r&&f){
cout<<l<<endl;
}else cout<<-1<<endl;
}
}
F
题意:
给定q个查询,每次查询l~r范围的数的异或和,刨除掉其中与k同模(2^i)的数x的异或值
思路:
神秘结论

那么l~r的异或值即f(r)^f(l-1)
现在考虑如何x的异或和
令x=k+j*2^i(j>=0)
由于l<=x<=r
有(l-k)<<i <= j <= (r-k)<<i
按位考虑
由于k是小于2^i的
所以k的二进制最高位是小于i的
[1,i-1]上只有k的二进制位,答案是否异或k取决于x的个数奇偶性
x的个数取决于j的个数,且x的[i,64)的二进制位异或为 xor(j,j+1,j+2,...)<<i
注意右边界小于0时,x的个数为0
int f(int x){
if(x%4==1){
return 1;
}else if(x%4==2){
return x+1;
}else if(x%4==3){
return 0;
}else{
return x;
}
}
void solve(){
int q;cin>>q;
while(q--){
int l,r,i,k;cin>>l>>r>>i>>k;
int ans=f(r)^f(l-1);
if(r<k){
cout<<ans<<endl;continue;
}
int left=(l-k-1>>i)+1;
int right=(r-k)>>i;
if(left<0)left=0;
if((right-left+1)&1)ans^=k;
ans^=((f(right)^f(max(0ll,left-1)))<<i);
cout<<ans<<endl;
}
}
G
题意:
交互题,有n种书,每种书两本,现在有三种各缺失了一本
每次可以查询[l,r]范围的书的编号(如果某种书有两本,则抵消)的异或值,求出三本缺失的书的编号
思路:
设答案书的编号为 a<b<c,
当xor[1,n]不为0时,可以利用单调性二分求出a和c(因为a xor b 和 b xor c一定不为0):
显然xor[1,a-1]=0,xor[1,a]=a
xor[c+1,n]=0,xor[c,n]=c
b=xor[1,n]^a^c
当xor[1,n]为0时,没有单调性,因为当区域xor为0时无法判断是[1,a-1]还是[1,c]
当三个数的异或值为0时,说明每一位的1的个数为偶数
发现b的最高位1一定不用于a的最高位1
所以可以枚举[1,2^i-1],当xor不等于0时,此时一定为a
然后b,c的范围为[2^i,n]
因为 b xor c一定不为0,所以可以再次利用二分求出b
void solve(){
int n;cin>>n;
cout<<"xor "<<1<<' '<<n<<endl;
cout.flush();
int xt;cin>>xt;
if(xt!=0){
int a=0,b=0,c=0;
int l=1,r=n;
while(l<=r){
int mid=l+r>>1;
cout<<"xor "<<1<<' '<<mid<<endl;cout.flush();
int x;cin>>x;
if(x==0){
l=mid+1;
}else{
a=mid;
r=mid-1;
}
}
l=1,r=n;
while(l<=r){
int mid=l+r>>1;
cout<<"xor "<<mid<<' '<<n<<endl;cout.flush();
int x;cin>>x;
if(x==0){
r=mid-1;
}else{
c=mid;
l=mid+1;
}
}
cout<<"ans "<<a<<' '<<(xt^a^c)<<' '<<c<<endl;
cout.flush();
return;
}
int a=0,b=0,c=0;
int l=1,r=n;
for(int i=1;i<64;i++){
if((1ull<<i)>n)break;
cout<<"xor "<<1<<' '<<((1ull<<i)-1)<<endl;cout.flush();
int x;cin>>x;
if(x!=0){
a=x;
l=(1ull<<i);
break;
}
}
int li=l;
while(l<=r){
int mid=l+r>>1;
cout<<"xor "<<li<<' '<<mid<<endl;cout.flush();
int x;cin>>x;
if(x!=0){
b=x;
r=mid-1;
}else{
l=mid+1;
}
}
cout<<"ans "<<a<<' '<<b<<' '<<(a^b)<<endl;
cout.flush();
}

浙公网安备 33010602011771号