好好好好好写暴力,不要因为觉得太简单了就乱写,最后少考虑了特殊情况。
现在是暴力会出这种错,以后写正解也少考虑情况就惨了。
LOGIC.
掌握时间复杂度的分析方法和常见算法的时间复杂度。
T1:
题意:
求l-r里的素数数。
分析:
垃圾T1毁我青春。
先打根号以内的素数表,再筛一次,注意第二次筛要限制max(i*i,lef/i*i),这样才能够尽量减少无意义的更改,免得T1就T。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
#define PROC "prime"
using namespace std;
const int Maxn=50005;
const int inf=200000000;
const int modd=1000000007;
long long lef,rig,n,m,pri[Maxn];
int idx,ans,vis[Maxn],vis2[Maxn*20];
long long read()
{
long long x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
void init()
{
lef=read();rig=read();
n=sqrt(double((double)rig+(double)1));
m=sqrt(double(n+1));
for(int i=2;i<=m;i++)if(!vis[i]){
pri[++idx]=i;
for(int j=i*i;j<=n;j+=i)
vis[j]=1;
}
for(int i=m+1;i<=n;i++)if(!vis[i])
pri[++idx]=i;
}
void work()
{
for(int i=1;i<=idx;i++)
for(long long j=max(pri[i]*pri[i],lef/pri[i]*pri[i]);j<=rig;j+=pri[i])
if(j>=lef)vis2[j-lef]=1;
for(int i=0;i<=rig-lef;i++)
if(!vis2[i])ans++;
printf("%d",ans);
}
int main()
{
freopen(PROC".in","r",stdin);
freopen(PROC".out","w",stdout);
init();
work();
return 0;
}
T2:
题意:
给定n,求1-n所有数每位上数的和。
分析:
随便画一下,根据每一位上每个数字构造出现次数(前面的次数乘以后面的次数),然后处理一下特殊情况即可。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
#define PROC "count"
using namespace std;
const int inf=200000000;
const int modd=1000000007;
long long ans;
long long n;
long long read()
{
long long x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
void init()
{
n=read();
}
void work()
{
for(long long i=1;i<=n;i*=10LL)
for(long long j=1;j<=9;j++)
if(i*j>n)break;
else{
ans+=j*(n/i/10LL)*i;
if((n/i)%10LL>j)ans+=j*i;
else if((n/i)%10LL==j)ans+=(n%i+1LL)*j;
}
printf(lld,ans);
}
int main()
{
freopen(PROC".in","r",stdin);
freopen(PROC".out","w",stdout);
init();
work();
return 0;
}
T3:
题意:
要求给定矩形是否被矩形内的车的攻击覆盖。车的攻击定义为其所在行&列。
分析:
分析题目特有特性可知(写暴力写着写着就发现了,又!没有深入想),横或竖至少有一个方向被全覆盖(这个不好证啊只能自己画一下了),所以扫两次看能不能行即可,然后是一个常见套路,就是要求最小,一定范围内,左边,所以可以拿一个条件作为顺序,在线查询线段树以维护两个条件。
还有一个套路就是,二维区间,二维可以拆分为一个循环一个线段树扫(扫描线),区间可拆分为时间和坐标、
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
#define PROC "brother"
using namespace std;
const int Maxn=200005;
const int inf=200000000;
const int modd=1000000007;
int canb[Maxn],n[2],k,q,kkk,cur1,cur2;
struct node1
{
int x[2];
}carr[Maxn];
bool cmp1(node1 x,node1 y)
{
return x.x[kkk]struct node2
{
int l[2],r[2],num;
}juxing[Maxn];
bool cmp2(node2 x,node2 y)
{
return x.r[kkk]struct node3
{
int lef,rig,maxn[2];
}a[Maxn<<2];
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
void build(int u,int lef,int rig)
{
a[u].lef=lef;a[u].rig=rig;
if(lef==rig)return;
int mid=(lef+rig)>>1;
build(2*u,lef,mid);
build(2*u+1,mid+1,rig);
}
void init()
{
n[0]=read();n[1]=read();
k=read();q=read();
for(int i=1;i<=k;i++){
carr[i].x[0]=read();
carr[i].x[1]=read();
}
for(int i=1;i<=q;i++){
juxing[i].num=i;
juxing[i].l[0]=read();
juxing[i].l[1]=read();
juxing[i].r[0]=read();
juxing[i].r[1]=read();
}
build(1,1,max(n[0],n[1]));
}
void update(int u,int loc,int val,int pd)
{
if(a[u].lef==loc&&a[u].rig==loc)
{a[u].maxn[pd]=val;return;}
int mid=(a[u].lef+a[u].rig)>>1;
if(loc<=mid)update(2*u,loc,val,pd);
else update(2*u+1,loc,val,pd);
a[u].maxn[pd]=min(a[2*u].maxn[pd],a[2*u+1].maxn[pd]);
}
int query(int u,int lef,int rig,int pd)
{
if(a[u].lef==lef&&a[u].rig==rig)
return a[u].maxn[pd];
int mid=(a[u].lef+a[u].rig)>>1;
if(rig<=mid)return query(2*u,lef,rig,pd);
else if(lef>mid)return query(2*u+1,lef,rig,pd);
return min(query(2*u,lef,mid,pd),query(2*u+1,mid+1,rig,pd));
}
void work()
{
for(kkk=0;kkk<=1;kkk++){
sort(carr+1,carr+k+1,cmp1);
sort(juxing+1,juxing+q+1,cmp2);
cur1=cur2=1;
for(int i=1;i<=n[kkk];i++){
while(carr[cur1].x[kkk]==i)
update(1,carr[cur1++].x[!kkk],i,kkk);
while(juxing[cur2].r[kkk]==i)
if((!canb[juxing[cur2].num])&&
query(1,juxing[cur2].l[!kkk],juxing[cur2].r[!kkk],kkk)>=juxing[cur2].l[kkk])
canb[juxing[cur2++].num]=1;
else cur2++;
}
}
for(int i=1;i<=q;i++)
if(canb[i])printf("YES\n");
else printf("NO\n");
}
int main()
{
freopen(PROC".in","r",stdin);
freopen(PROC".out","w",stdout);
init();
work();
return 0;
}