小白赛5:
A题意:
若一个集合A内所有的元素都不是正整数N的因数,则称N与集合A无关。
给出一个含有k个元素的集合A={a1,a2,a3,...,ak},求区间[L,R]内与A无关的正整数的个数。 保证A内的元素都是素数。
1<=L<=R<=10^18,1<=k<=20,2<=ai<=100
题解:用相容定理找出有关的数相减
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <map>
using namespace std;
#define LL unsigned long long
const int maxn = 1e2+3;
LL l,r,k;
LL a[maxn];
LL sum=0;
void dfs(LL x,LL now,LL c)
{
if(x>r) return;
if(c&1){
sum+=r/x-(l-1)/x;
}else{
sum-=r/x-(l-1)/x;
}
for(LL i=now+1;i<=k;i++){
dfs(x*a[i],i,c+1);
}
}
int main()
{
while(~scanf("%llu%llu%llu",&l,&r,&k)){
sum=0;
for(LL i=1;i<=k;i++)
scanf("%llu",&a[i]);
for(LL i=1;i<=k;i++)
dfs(a[i],i,1);
printf("%llu\n",(r-l+1)-sum);
}
}
I:
链接:https://www.nowcoder.com/acm/contest/135/I
theme:有一个n个元素的数组a,而他要对a[L]-a[R]进行M次操作: 操作一:将a[L]-a[R]内的元素都加上P 操作二:将a[L]-a[R]内的元素都减去P 最后询问a[l]-a[r]内的元素之和?
solution:线段树超内存 400万32兆吃力,这题只算一次区间和,直接用前缀和
前缀和AC代码:
#include<iostream>
using namespace std;
typedef long long ll;
int const SIZE=1000010;
ll a[SIZE];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;++i)
cin>>a[i];
/*对数组初始化为该项与前一项的和*/
for(int i=n;i>1;--i)
a[i]=a[i]-a[i-1];
int q,l,r,p;
/*区间修改只对左边界(增加则加)和右边界后一个(增加则减)修改*/
while(m--)
{
cin>>q>>l>>r>>p;
if(q==1)
a[l]-=p,a[r+1]+=p;
else
a[l]+=p,a[r+1]-=p;
}
cin>>l>>r;
ll sum=0;
/*最后还原求区间和时一定要从头开始加,每一项等于本身加上前一项*/
for(int i=2;i<=n;++i)
a[i]=a[i]+a[i-1];
for(int i=l;i<=r;++i)
sum+=a[i];
cout<<sum<<endl;
}
附上线段树代码:
#include<iostream>
using namespace std;
typedef long long ll;
int const SIZE=1000010;
struct tree
{
int bj;
int sum;
}T[4*SIZE];
int a[SIZE];
void build(int k,int l,int r)
{
T[k].bj=0;
if(l==r)
{
cin>>a[l];
T[k].sum=a[l];
}
else
{
int mid=(l+r)/2;
build(k<<1,l,mid);
build((k<<1)+1,mid+1,r);
T[k].sum=T[k<<1].sum+T[(k<<1)+1].sum;
}
}
void update(int k,int l1,int r1,int l2,int r2)
{
T[k<<1].sum+=T[k].bj*(r1-l1+1);
T[(k<<1)+1].sum+=T[k].bj*(r2-l2+1);
T[k<<1].bj+=T[k].bj;
T[(k<<1)+1].bj+=T[k].bj;
T[k].bj=0;
}
void add(int k,int s,int e,int delta,int l,int r)
{
if(s==l&&r==e)
{
T[k].sum+=delta*(r-l+1);
T[k].bj+=delta;
}
else
{
int mid=(l+r)/2;
if(T[k].bj)update(k,l,mid,mid+1,r);
if(e<=mid)
add(k<<1,s,e,delta,l,mid);
else if(s>mid)
add((k<<1)+1,s,e,delta,mid+1,r);
else
{
add(k<<1,s,mid,delta,l,mid);
add((k<<1)+1,mid+1,e,delta,mid+1,r);
}
T[k].sum=T[k<<1].sum+T[(k<<1)+1].sum;
}
}
ll query(int k,int s,int e,int l,int r)
{
if(l==s&&r==e)return T[k].sum;
int mid=(l+r)/2;
if(T[k].bj)update(k,l,mid,mid+1,r);
ll ans=0;
if(e<=mid)
ans+=query(k<<1,s,e,l,mid);
else if(s>mid)
ans+=query((k<<1)+1,s,e,mid+1,r);
else
ans+=query(k<<1,s,mid,l,mid)+query((k<<1)+1,mid+1,e,mid+1,r);
return ans;
}
int main()
{
int n,m;
cin>>n>>m;
build(1,1,n);
int q;
int l,r,p;
while(m--)
{
cin>>q>>l>>r>>p;
if(q==1)
add(1,l,r,-p,1,n);
else
add(1,l,r,p,1,n);
}
cin>>l>>r;
ll ans;
ans=query(1,l,r,1,n);
cout<<ans;
}