牛客练习赛33

这题WildCow学长出的

C不想写结果最后中奖了2333

A:水题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll l,r,x;
ll F(ll y){
    return y/x;
}
int main(){
    int T;
    cin>>T;
    while(T--){
    cin>>l>>r>>x;
    cout<<F(r)-F(l-1)<<endl;
    }
}

 

B:一个线性筛,先统计一下,然后晒得时候乘个系数就行了,一个一个倍数标记肯定超时,比如输入的全是1的时候。

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int A[N],ANS[N];
int main(){
    int n,k,x;
    cin>>n>>k;
    for(int i=1;i<=n;++i)scanf("%d",&x),A[x]++;
    for(int i=1;i<=k;++i){
        if(A[i]==0)continue;
        for(int j=i;j<=k;j+=i){
            ANS[j]+=A[i];
        }
    }
    int ans=0;
    for(int i=1;i<=k;++i){
        ans=max(ans,ANS[i]);
    }
    int ans2=0;
    for(int i=1;i<=k;++i){
        if(ans==ANS[i])++ans2;
    }
    cout<<ans<<" "<<ans2<<endl;
}

 

C:不想写,看最后三位能判断是否整除然后前边排序输出

 

D:一点小思维,把一个区间的一部分放到后边,涉及到的 数对 会取补,一开始看下逆序对的奇偶,连树状数组都不用,直接看置换环的奇偶,然后每次询问看涉及到的 数对 的奇偶

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int A[N],B[N];
int main(){
    int n;
    scanf("%d",&n);
    int ans=0;
    for(int i=1;i<=n;++i)scanf("%d",&A[i]);
    for(int i=1;i<=n;++i){
        if(B[i]==0){
            ++ans;
            B[i]=1;
            int now=A[i];
            while(B[now]==0){
                B[now]=1;
                now=A[now];
            }
        }
    }
    ans%=2;
    int m;
    scanf("%d",&m);
    while(m--){
        ll x,y,z;
        scanf("%lld%lld%lld",&x,&y,&z);
        z%=(y-x+1);
        ll Ans=(y-x+1-z)*z;
        if(Ans%2==1){
            ans=!ans;
            printf("%d\n",ans);
        }else{
            printf("%d\n",ans);
        }
    }
}

 

E:构造26个HASH函数,一个连续n个1的HASH值,之后加减比较,这题一开始不知道脑子抽啥风,直接干了个线段树上去,mdzz。

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int N=1e5+10;
char s[N];
ll F[N][26],P[N],G[N];
ll get(int l,int r,int x){
    return F[r][x]-F[l-1][x]*P[r-l+1];
}
int main(){
    int n,m;
    scanf("%d",&n);
    scanf("%s",s+1);
    P[0]=1;
    for(int i=1;i<=n;++i){
        for(int j=0;j<=s[i]-'a';++j){
            F[i][j]=F[i-1][j]*131+s[i]-'a';
        }
        for(int j=s[i]-'a';j<26;++j){
            F[i][j]=F[i-1][j]*131+s[i]-'a'+26;
        }
        P[i]=P[i-1]*131;
    }
    for(int i=1;i<=n;++i){
        G[i]=G[i-1]*131+1;
    }
    scanf("%d",&m);
    while(m--){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        int a=s[x]-'a';
        int b=s[y]-'a';
        if(a>b){
            if(get(x,x+z-1,a)==get(y,y+z-1,b)+G[z]*(a-b))printf("%d\n",min(a-b,26-a+b));
            else printf("-1\n");
        }else{
            if(get(x,x+z-1,a)+G[z]*(b-a)==get(y,y+z-1,b))printf("%d\n",min(b-a,26-b+a));
            else printf("-1\n");
        }
    }
}

 

F:纸上找找规律会发现就是A[n][n]的值,然后有个长度为n的式子,一直卡在这个式子怎么算,后来打了下表发现就是阶乘,然后搜了个大数阶乘取模的板子,原理是分段打表:

#include<iostream>
#include<cstdio>
#define lon long long
using namespace std;
lon A[1010],B[1010];
lon n,p;
lon a[110]={1,682498929,491101308,76479948,723816384,67347853,27368307,
625544428,199888908,888050723,927880474,281863274,661224977,623534362,
970055531,261384175,195888993,66404266,547665832,109838563,933245637,
724691727,368925948,268838846,136026497,112390913,135498044,217544623,
419363534,500780548,668123525,128487469,30977140,522049725,309058615,
386027524,189239124,148528617,940567523,917084264,429277690,996164327,
358655417,568392357,780072518,462639908,275105629,909210595,99199382,
703397904,733333339,97830135,608823837,256141983,141827977,696628828,
637939935,811575797,848924691,131772368,724464507,272814771,326159309,
456152084,903466878,92255682,769795511,373745190,606241871,825871994,
957939114,435887178,852304035,663307737,375297772,217598709,624148346,
671734977,624500515,748510389,203191898,423951674,629786193,672850561,
814362881,823845496,116667533,256473217,627655552,245795606,586445753,
172114298,193781724,778983779,83868974,315103615,965785236,492741665,
377329025,847549272,698611116};
int main()
{
    int m;
    p=1000000007;
    cin>>n>>m;
    for(int i=1;i<=m;++i)cin>>A[i]>>B[i];
    lon ANS;
    for(int i=1;i<=m;++i){
        if(B[i]==n){
            ANS=A[i];
        }
    }
        lon now=n/10000000;
        lon ans=a[now];
        for(lon i=now*10000000+1;i<=n;i++)
        ans=ans*i%p;
        cout<<ans*ANS%p;
        return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值