简单瞎搞题
不会用bitset,所以没做出来。实际上还是比较简单的。
#include<bits/stdc++.h>
using namespace std;
bitset<1000005>dp[2];
int main()
{
int n;
cin>>n;
int l,r;
dp[0][0]=1;
for(int i=1;i<=n;i++)
{
dp[i%2].reset();
scanf("%d %d",&l,&r);
for(int j=l;j<=r;j++)
dp[i%2]|=(dp[(i-1)%2]<<(j*j));
}
cout<<dp[n%2].count()<<endl;
}
简单数据结构1
这里要运用拓展欧拉定理。
abmodp=ab%Φ(p)+(b≥Φ(p)?Φ(p):0)mod p
a
b
m
o
d
p
=
a
b
%
Φ
(
p
)
+
(
b
≥
Φ
(
p
)
?
Φ
(
p
)
:
0
)
m
o
d
p
实际上看到这个等式时,我想写递归但写不出来。。因为这个等式并不是递归的形式。。
所以我看别人的题解,实际上我们定义上面式子重新定义一个fmod(x,p)=x%p+x>=p?x:0
这个mod和原来的mod实际上就是可能多个模数,但是我们再模一次就能消除影响了。既然用这个mod那么原来的式子就能写成
abfmodp=abfmodΦ(p)fmodp
a
b
f
m
o
d
p
=
a
b
f
m
o
d
Φ
(
p
)
f
m
o
d
p
,现在就是递归形式啦,当我们计算时需要用到快速幂,而快速幂的模也可以用同样的方式,仔细想想就会明白没有任何影响。
在最后的答案需要再模p一下。
区间修改单点查询用树状数组就完事了。
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
const int maxn=5e5+5;
int phi[20000005];
void init(int n)
{
for(int i=2;i<=n;i++)phi[i]=0;
phi[1]=1;
for(int i=2;i<=n;i++)if(!phi[i])
for(int j=i;j<=n;j+=i)
{
if(!phi[j])phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}
int a[maxn];
long long sum[maxn];
void add(int x,int num)
{
while(x<maxn)
{
sum[x]+=num;
x+=lowbit(x);
}
}
long long query(int x)
{
long long res=0;
while(x)
{
res+=sum[x];
x-=lowbit(x);
}
return res;
}
int fmod(long long a,int p)
{
return a%p+(a>=p?p:0);
}
int quick_mul(int a,int num,int p)
{
int res=1;
while(num)
{
if(num%2)res=fmod(1LL*res*a,p);
a=fmod(1LL*a*a,p);
num/=2;
}
return res;
}
int Q(int l,int r,int p)
{
if(l==r)
return fmod(query(l)+a[l],p);
int thephi=phi[p];
if(thephi==1)
return fmod(query(l)+a[l],p);
return quick_mul(fmod(query(l)+a[l],p),Q(l+1,r,thephi),p);
}
int main()
{
init(20000000);
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
int opt,l,r,p;
while(m--)
{
scanf("%d %d %d %d",&opt,&l,&r,&p);
if(opt==1)
{
add(l,p);
add(r+1,-p);
}
else
printf("%d\n",Q(l,r,p)%p);
}
return 0;
}
牛客老是打不好,还是得多补题啊。