A. Nastya and an Array
水题,暴力
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<set>
#include<map>
#include<stack>
#include<queue>
using namespace std;
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define eps 1e-10
const int N = 1e5+10;
int n,num;
ll ans;
int main() {
ios::sync_with_stdio(0);
cin>>n;
set<int> s;
for(int i=1;i<=n;i++) {
cin>>num;
if(num) s.insert(num);
}
cout<<s.size()<<endl;
return 0;
}
B. Nastya Studies Informatics
数论、思维枚举
a*b=x*y,a=n*m,b=m*z.则x=m,y=n*m*z。考虑枚举n的所有可能,复杂度为O(sqrt(n))。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<set>
#include<map>
#include<stack>
#include<queue>
using namespace std;
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define eps 1e-10
const int N = 3e5+10;
int n;
ll l,r,x,y,ans;
ll gcd(ll a,ll b) {
if(b==0) return a;
else return gcd(b,a%b);
}
int main() {
ios::sync_with_stdio(0);
cin>>l>>r>>x>>y;
if(y%x) cout<<0<<endl;
else {
ll tp=y/x;
for(ll i=1;i*i<=tp;i++) {
if(tp%i==0 && gcd(tp/i,i)==1 && l<=i*x&&i*x<=r && l<=tp/i*x&&tp/i*x<=r) {
if(tp/i==i) ans++;
else ans+=2;
}
}
cout<<ans<<endl;
}
return 0;
}
C. Nastya and a Wardrobe
数学
S1=2*x,S2=2*S1-1,可以用矩阵递推或者直接用公式,Sk=(2*x*2^k-(2^k-1))%p,注意特判x,k为0的情况。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<set>
#include<map>
#include<stack>
#include<queue>
using namespace std;
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define eps 1e-10
const int N = 3e5+10;
const ll p = 1e9+7;
int n;
ll ans;
ll qp(ll a,ll b) {
ll s=1;
while(b) {
if(b&1) s=s*a%p;
a=a*a%p,b/=2;
}
return s;
}
int main() {
ios::sync_with_stdio(0);
ll x,k;
cin>>x>>k;
if(k==0) cout<<2*x%p<<endl;
else if(x==0) cout<<0<<endl;
else {
x*=2;
cout<<(x%p*qp(2,k)%p-(qp(2,k)+p-1)%p+p)%p<<endl;
}
return 0;
}
D. Nastya and a Game
数学(给一个数列,求出子区间个数,要求满足∏rlai=K∗∑rlai )
观察等式右边最大值为为2e18不超过long long ,如果等式左边溢出long long 则以此数开头的序列不可能再满足等式,
如果ai>=2,那么不超过64次就会结束,如果出现多个1的情况,此时等式左边不会改变,记录下每个1可连续延伸的最
大下标,直接跳过这一段并直接判断是否有满足条件的情况,最多不跳过64次,所以复杂度为O(n*log2e18)(O(64*n))左右。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<set>
#include<map>
#include<stack>
#include<queue>
using namespace std;
#define ll long long
#define pb push_back
#define inf LLONG_MAX
#define eps 1e-10
const int N = 3e5+10;
ll n,k,a[N],nt[N],ans;
int of(ll a,ll b) {
if(a>=inf/b) return 1;
return 0;
}
int main() {
ios::sync_with_stdio(0);cin.tie(0);
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
int pos=n,f=1;
for(int i=n;i>=1;i--) {///nt数组记录每一个1可连续下去的最大下标
if(a[i]==1) {
if(f) pos=i,f=0;
nt[i]=pos;
}else f=1;
}
for(int i=1;i<=n;i++) {
ll p=1,s=0;
for(int j=i;j<=n;) {
if(nt[j]) {
if(s*k<p && p%k==0 && (s+nt[j]-j+1)*k>=p ) ans++;///判断连续1中是否有满足条件的情况
s+=(nt[j]-j+1),j=nt[j]+1;
}
else {
if(of(p,a[j])) break;///溢出则退出
p*=a[j],s+=a[j];
if(p==s*k) ans++;
j++;
}
}
}
cout<<ans<<endl;
return 0;
}
E. Nastya and King-Shamans
数据结构、二分查找
未做,日后补上。
∏rlai=K∗∑rlai∏lrai=K∗∑lrai