牛客小白月赛9 A B C E F H J

 

/**
A	签到
链接:https://ac.nowcoder.com/acm/contest/275/A
ans:1-都没有扔下来的概率; 处理逆元取模即可
*/

#include<bits/stdc++.h>
#define  ll long long
using namespace std;

const int mod=1e9+7;

ll ksm(ll a,ll b){
	ll ans=1;
	while(b){
		if(b&1) ans=ans*a%mod;
		b>>=1;
		a=a*a%mod;
	}
	return ans;
}

int main (){
	int n;scanf("%d",&n);
	ll p=1,q=1;
	for(int i=0;i<n;i++){
		int a,b;scanf("%d %d",&a,&b);
		p=p*1ll*(b-a)%mod;
		q=q*1ll*ksm(b*1ll,mod-2)%mod;
	}
	cout<<(1-p*q%mod+mod)%mod<<endl;
	return 0;
}

 

/**
B	法法
链接:https://ac.nowcoder.com/acm/contest/275/B
题意:如中文题面;
分析:对每个数字都存在*A(n-1,n-1),ans:n*A(n-1,n-1)*sum;sum为常数;
由于A(n-1,n-1)从第三项开始就是偶数,由于ans:ans%2--->{n>3,ans=0}
*/

#include<bits/stdc++.h>
#define  ll long long
using namespace std;
int main (){
	int t;cin>>t;
	while(t--){
		ll n;cin>>n;
		if(n<=2) printf("1\n");
		else printf("0\n");
	}
	return 0;
}
/**
C	红球进黑洞
链接:https://ac.nowcoder.com/acm/contest/275/C
题意:区间求和+区间异或;
分析:区间异或操作,脸上写着线段树吧!!!!,分块不行的吧????;
首先可以对于一个数的二进制进行操作,最多20位;
因此可以用第i颗线段树来维护二进制第i位的个数,最后奇偶即可;
区间异或:[l,r]更新后1的数量等于(r-l+1)-更新前1的数量
区间求和:[l,r]1的数量*当前位值


*/

#include <bits/stdc++.h>
#define lmid ((l + r) >> 1)
#define rmid (lmid + 1)
#define lson 2 * o + 1, l, lmid
#define rson 2 * o + 2, rmid, r
using namespace std;

const int maxn=1e5 + 5;
const int M=20;
int cnt[4*maxn][M],tag[4*maxn][M], a[maxn], n, m;

void pushup(int o, int l, int r) {
    for(int i = 0; i < 20; i++) {
        cnt[o][i] = 0;
        if(tag[2 * o + 1][i]) cnt[o][i] += lmid + 1 - l - cnt[2 * o + 1][i];
        else cnt[o][i] += cnt[2 * o + 1][i];
        if(tag[2 * o + 2][i]) cnt[o][i] += r + 1 - rmid - cnt[2 * o + 2][i];
        else cnt[o][i] += cnt[2 * o + 2][i];
    }
}
void pushdown(int o) {
    for(int i = 0; i < 20; i++)  tag[2 * o + 1][i] ^= tag[o][i],tag[2 * o + 2][i] ^= tag[o][i],tag[o][i] = 0;
    return;
}
void build(int o, int l, int r) {
    if(l == r) {
        for(int i = 0; i < 20; i++)
            if(a[l] >> i & 1) cnt[o][i] = 1;
        return;
    }
    build(lson);
    build(rson);
    pushup(o, l, r);
}
void modify(int o, int l, int r, int L, int R, int k) {
    if(r < L || R < l) return;
    else if(L <= l && r <= R) {
        for(int i = 0; i < 20; i++) if(k >> i & 1) tag[o][i] ^= 1;
        return;
    }
    modify(lson, L, R, k),modify(rson, L, R, k);
    pushdown(o);
    pushup(o, l, r);
}
long long query(int o, int l, int r, int L, int R) {
    if(r < L || R < l) return 0;
    else {
        if(L <= l && r <= R) {
            long long res = 0;
            for(int i = 0; i < 20; i++) {
                if(tag[o][i]) res += (1ll << i) * (r - l + 1 - cnt[o][i]);
                else res += (1ll << i) * cnt[o][i];
            }
            return res;
        }
        else {
            pushdown(o);
            long long res = query(lson, L, R) + query(rson, L, R);
            pushup(o, l, r);
            return res;
        }
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    build(0, 1, n);
    while(m--) {
        int opt,l, r, k;
        scanf("%d%d%d", &opt, &l, &r);
        if(opt == 1) printf("%lld\n", query(0, 1, n, l, r));
        else {
            scanf("%d", &k);
            modify(0, 1, n, l, r, k);
        }
    }
}

 

/**
E	换个角度思考
链接:https://ac.nowcoder.com/acm/contest/275/E
分块即可
*/

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e5+7;
vector<int>vec[500];

int pos[maxn],s[maxn],blo,n,m;

int query(int l,int r,int k){
	int ans=0;
	for(int i=pos[l]+1;i<=pos[r]-1;i++) ans+=upper_bound(vec[i].begin(),vec[i].end(),k)-vec[i].begin();
	if(pos[l]!=pos[r]){
		for(int i=l;i<=pos[l]*blo;i++) if(s[i]<=k) ans++;
		for(int i=(pos[r]-1)*blo+1;i<=r;i++) if(s[i]<=k) ans++;
	}
	else for(int i=l;i<=r;i++) if(s[i]<=k) ans++;
	return ans;
}

int main (){
	scanf("%d %d",&n,&m);blo=(int)sqrt(n*1.0);
	for(int i=1;i<=n;i++) pos[i]=(i-1)/blo+1,scanf("%d",&s[i]);
	for(int i=1;i<=pos[n];i++){
		for(int j=(i-1)*blo+1;j<=min(i*blo,n);j++)vec[i].push_back(s[j]);
	}
	for(int i=1;i<=pos[n];i++) sort(vec[i].begin(),vec[i].end());
	while(m--){
		int l,r,k;scanf("%d %d %d",&l,&r,&k);
		printf("%d\n",query(l,r,k));
	}
	return 0;
}

 

/**
F	暴力出奇迹
链接:https://ac.nowcoder.com/acm/contest/275/F

题意:二进制贪心,对当前位置贡献为连续1的则记录答案;
和线性基的想法类似,选择对于当前位存在贡献的一位;
*/

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn=1e5+7;
int a[maxn],n;

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    ll ans=0;
    for(int i=0;i<20;i++){
		ll tmp=a[1],sum=0;
		for(int j=1;j<=n;j++){
			if(a[j]>>i&1){
				tmp&=a[j];
				sum+=a[j];
				ans=max(ans,tmp*sum);
			}
			else {
				tmp=a[j+1];
				sum=0;
			}
		}
    }
    printf("%lld\n",ans);
    return 0;
}
/**
H	论如何出一道水题
链接:https://ac.nowcoder.com/acm/contest/275/H
n 与 n-1 互质
特判1即可;

*/

#include<bits/stdc++.h>
using namespace std;

int main(){
    long long  n;cin>>n;
    if(n==1) cout<<2<<endl;
    else cout<<n+n-1<<endl;
    return 0;
}

 

 

/**
J	div.2 A
链接:https://ac.nowcoder.com/acm/contest/275/J

题意:f(n,k) n拆分为k个有序正整数乘积的方案数;
ans = segment( (f(i,k)+i))%mod) i-->[1,n];

分析:f(n,k)=C(num_p1+k-1,k-1)*C(num_p2+k-1,k-1)*.....C(num_pcnt+k-1,k-1)......
num_pi:n不同质因子的数量;
f(n,k):可考虑经典球盒问题,将长度为k的盒子初始化,均赋值为1,将质因子做为球丢进即可;

ans:显然当前这题是需要趋近于O(n)的方法来实现的,不妨想到欧拉筛选素数;
在筛选过程,每个数可用num[i],记录i在当前情况下,未用的最小质因子的数量,由此进行递推即可;
每次i%prime[j]==0,也就是当前的i已经被最小的已经用过的质因子使用过了;
但是可能还存在,对于当前过程,只增加1,递推可得当前ans;
对于新的质因子表示:用过的质因子的个数已经全部被取完了,*k即可;

如果采用普通的素数筛选方法,貌似会炸空间 且时间复杂度不会得到保证;

*/

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn=1e7+7;
const int mod=1e9+7;
int prime[maxn],ans[maxn],num[maxn],cnt=0;

const int inv_num=1e2+7;
int inv[inv_num+3];

int main (){
	ll k;int n;cin>>n>>k;k%=mod;
	inv[1]=1,ans[1]=1;
	for(int i=2;i<=100;i++) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;//质因子数量最多为64:
	for(int i=2;i<=n;i++){
		if(!prime[i]){
			prime[++cnt]=i;
			ans[i]=k,num[i]=1;//素数:
		}
		for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
			prime[i*prime[j]]=1;
			if(i%prime[j]==0){
				ans[i*prime[j]]=1ll*ans[i]*(num[i]+k)%mod*inv[num[i]+1]%mod;//C(num[i]+k-1,k-1)-->C(num[i]+k-1+1,k-1);
				num[i*prime[j]]=num[i]+1;//引进旧因子;
				break;
			}
			ans[i*prime[j]]=1ll*ans[i]*k%mod;
			num[i*prime[j]]=1;//新查询的因子
		}
	}
	int ret=0;
	for(int i=1;i<=n;i++) ret^=(ans[i]+i)%mod;
	printf("%d\n",ret);
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值