A
模拟,判断y>=x且y<=x+n-m是否成立。
#include<bits/stdc++.h>
using namespace std;
#define maxx 3000
int n,a,b,c,s,m,t,x,y;
map<int,int> M;
pair<int,int> all[maxx];
int ans=0;
int anss=0;
int main()
{
cin>>t;
for(int i=1;i<=t;++i)
{cin>>n>>m>>x>>y;
if(y>=x&&y<=x+n-m)
cout<<"Yes\n";
else
cout<<"No\n";
}
}
B
设一个合法解为a,b,则gcd(a,b)=x,lcm(a,b)=y,而gcd(a,b)*lcm(a,b)=x*y=a*b。
则a与b是xy的约数,枚举所有约数后判断是否gcd(a,b)=x,从小到大枚举。
#include<bits/stdc++.h>
using namespace std;
#define maxx 3000
#define int long long
int n,a,b,c,s,m,t,x,y;
pair<int,int> all[maxx];
int ans=0;
int anss=0;
signed main()
{
cin>>t;
for(int i=1;i<=t;++i)
{cin>>x>>y;
int z=x*y;
for(int i=1;i<=sqrt(z);++i)
{
if(z%i!=0) continue;
if(__gcd(i,z/i)==x)
{
cout<<i<<" "<<z/i<<"\n";
goto h;
}
}
cout<<-1<<"\n";
h:;
}
}
C
贪心
题目可以转换为bi∈[ai-k,ai+k],且bi非减。
为了减少前数字对后面的影响,每个点尽量向右取和向左取且保证合法,分别判断。
#include<bits/stdc++.h>
using namespace std;
#define maxx 1200000
int n,a,b,c,s,m,t,x,y,k;
int all[maxx];
int ans=0;
int anss=0;
int main()
{
cin>>t;
for(int i=1;i<=t;++i)
{cin>>n>>k;
for(int i=1;i<=n;++i)
cin>>all[i];
int x=all[1]-k;
int wr=0;
for(int i=2;i<=n;++i)
{
if(all[i]+k<x)
{
++wr;
break;
}
else if(all[i]-k<=x&&all[i]+k>=x) ;
else x=all[i]-k;
}
x=all[1]+k;
for(int i=2;i<=n;++i)
{
if(all[i]+k<x)
{
++wr;
break;
}
else x=all[i]+k;
}
if(wr==2) cout<<"No\n";
else cout<<"Yes\n";
}
}
D
注意题意:1.是翻转不是反转,2.每次处理独立,而不是逐步修改。
如果1,2均满足后者,需要使用线段树来进行处理,大约如下代码,没做验证。
#include<bits/stdc++.h>
using namespace std;
#define INF 1e18
#define maxx 5080000
#define maxx2 0x3f3f3f3f
int a,b,d,k,m,t,n,ansmax,Smax,x,ans1,ans2,neww,c;
int l,r,q;
string s;
int xmax,ymax;
int pj;
int sum=0;
int all[maxx];
struct point
{
int sum0,sum1;//连续的个数
int ld,rd;
int leng;
int tag;
}JD[maxx];
int ls(int root)
{
return 2*root;
}
int rs(int root)
{
return 2*root+1;
}
void update_from_son(int root,int l,int r)
{
int mid=(l+r)/2;
JD[root].ld=JD[ls(root)].ld;
JD[root].rd=JD[rs(root)].rd;
JD[root].sum0=JD[ls(root)].sum0+JD[rs(root)].sum0;
JD[root].sum1=JD[ls(root)].sum1+JD[rs(root)].sum1;
JD[root].leng=JD[ls(root)].leng;
if(JD[ls(root)].rd==JD[rs(root)].ld&&JD[ls(root)].rd==0)
--JD[root].sum0;
if(JD[ls(root)].rd==JD[rs(root)].ld&&JD[ls(root)].rd==1)
--JD[root].sum1;
if(JD[ls(root)].leng==mid-l+1&&JD[ls(root)].rd==JD[rs(root)].ld)
JD[root].leng=JD[root].leng+JD[rs(root)].leng;
}
void push_down(int root)
{
if(JD[root].tag==0) return ;
JD[ls(root)].tag=(JD[ls(root)].tag+1)%2;
JD[rs(root)].tag=(JD[rs(root)].tag+1)%2;
JD[ls(root)].ld=(JD[ls(root)].ld+1)%2;
JD[ls(root)].rd=(JD[ls(root)].rd+1)%2;
swap(JD[ls(root)].sum0,JD[ls(root)].sum1);
JD[rs(root)].ld=(JD[rs(root)].ld+1)%2;
JD[rs(root)].rd=(JD[rs(root)].rd+1)%2;
swap(JD[rs(root)].sum0,JD[rs(root)].sum1);
}
void build(int root,int l,int r)
{
if(l==r)
{
if(all[l]==1) JD[root].sum1=1;
else JD[root].sum0=1;
JD[root].ld=all[l];
JD[root].rd=all[l];
JD[root].leng=1;
return;
}
int mid=(l+r)/2;
build(ls(root),l,mid);
build(rs(root),mid+1,r);
update_from_son(root,l,r);
}
void modify(int root,int l,int r,int ql,int qr)
{
if(l==ql&&r==qr)
{
JD[root].ld=(JD[root].ld+1)%2;
JD[root].rd=(JD[root].rd+1)%2;
swap(JD[root].sum0,JD[root].sum1);
JD[root].tag=(JD[root].tag+1)%2;
return ;
}
int mid=(l+r)/2;
push_down(root);
if(ql<=mid) modify(ls(root),l,mid,ql,min(qr,mid));
if(qr>=mid+1) modify(rs(root),mid+1,r,max(mid+1,ql),qr);
update_from_son(root,l,r);
}
int query(int root,int l,int r)
{
return JD[1].sum1;
}
signed main()
{
cin>>n>>q>>s;
for(int i=0;i<n;++i)
all[i+1]=s[i]-'0';
build(1,1,n);
for(int i=1;i<=q;++i)
{
cin>>l>>r;
modify(1,1,n,l,r);
cout<<query(1,1,n)<<"\n";
}
}
正解为如下
首先处理出所有连续1段的长度,然后翻转在左右端点不一致的时候会影响端点的数值,在端点分类讨论即可。
#include<bits/stdc++.h>
using namespace std;
#define INF 1e18
#define maxx 88
#define maxx2 0x3f3f3f3f
int a,b,d,k,m,t,n,ansmax,Smax,x,ans1,ans2,neww,c;
int q;
string s;
int l,r;
int xmax,ymax;
int pj;
int sum=0;
int all[maxx];
int ans;
signed main()
{
cin>>n>>q>>s;
for(int i=0;i<n;++i)
all[i+1]=s[i]-'0';
int x=1;
for(int i=1;i<=n;)
{
x=i;
while(++i<=n)
{
if(all[i]!=all[x])
{
if(all[x]==1) ++ans;
x=i;
break;
}
}
}
if(all[n]==1)
++ans;
all[0]=all[n+1]=-1;
for(int i=1;i<=q;++i)
{
cin>>l>>r;
int qq=ans;
if(all[l]==0&&all[r]==1&&all[l-1]!=1) ++qq;
if(all[l]==0&&all[r]==1&&all[r+1]!=1) --qq;
if(all[l]==1&&all[r]==0&&all[l-1]!=1) --qq;
if(all[l]==1&&all[r]==0&&all[r+1]!=1) ++qq;
cout<<qq<<"\n";
}
}



京公网安备 11010502036488号