士兵杀敌 1-5

本文详细解析了士兵杀敌系列算法题目,包括基本数组操作、树状数组、RMQ算法及其实现方法等,通过具体实例展示了不同算法的运用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

士兵杀敌一:

nyoj原题链接

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int n,m;    scanf("%d%d",&n,&m);
    int *num;int i;int a,b; long long *sum;
    num=(int*)malloc(n*sizeof(int));
    sum=(long long *)malloc((n+1)*sizeof(long long));
    for(i=0;i<n;i++)
    scanf("%d",&num[i]);sum[0]=0;
    for(i=1;i<=n;i++)
    sum[i]=sum[i-1]+num[i-1];
    while(m--)
    {
        int sum1=0;
        scanf("%d%d",&a,&b);
        sum1=sum[b]-sum[a-1];
        printf("%d\n",sum1);
    }
    return 0;
}

树状数组图解:
树状数组结构

士兵杀敌二

nyoj原题链接

#include<stdio.h>
#include<stdlib.h>
long long* Sum;int N,M;
void Add(int j,int k)
{
    while(j<=N)
    {
        Sum[j]+=k;
        j+=(j&-j);
    }
}
int Query(int j)
{
    int s=0;
    while(j>0)
    {
        s+=Sum[j];
        j-=(j&-j);
    }
    return s;
}
int main()
{
    int* A;int i;
    scanf("%d%d",&N,&M);char str[6];int a,b;
    A=(int *)malloc((N+1)*sizeof(int));
    Sum=(long long*)malloc((N+1)*sizeof(long long));
    for(i=0;i<=N;i++) Sum[i]=0;
    for(i=1;i<=N;i++)
        scanf("%d",&A[i]);
    for(i=1;i<=N;i++) Add(i,A[i]);
    while(M--)
    {
        scanf("%s%d%d",str,&a,&b);
        if(str[0]=='Q'){
            printf("%d\n",query(b)-query(a-1));
        }
        if(str[0]=='A')
        Add(a,b);
    }
    return 0;
}

士兵杀敌三

nyoj原题链接


//rmq算法
#include<stdio.h>
#include<math.h>
#define N 100001
int maxsum[20][N];int minsum[20][N];
int Max(int a,int b)
{
    return a>b?a:b;
} 
int Min(int a,int b)
{
    return a<b?a:b;
}
void Rmq(int num)   //预处理!!!! 
{
    for(int i=1;i<20;i++)
    for(int j=1;j<=num;j++)
    if(j+(1<<i)-1<=num){
        maxsum[i][j]=Max(maxsum[i-1][j],maxsum[i-1][j+(1<<i>>1)]);
        minsum[i][j]=Min(minsum[i-1][j],minsum[i-1][j+(1<<i>>1)]);
    }
}
int main()
{
    int n,q;int i;int a,b;
    scanf("%d%d",&n,&q);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&maxsum[0][i]);
        minsum[0][i]=maxsum[0][i];
    }
    Rmq(n);
    while(q--)
    {
        scanf("%d%d",&a,&b);
        int k=log(b-a+1.0)/log(2.0);
        int max=Max(maxsum[k][a],maxsum[k][b-(1<<k)+1]);
        int min=Min(minsum[k][a],minsum[k][b-(1<<k)+1]);
        printf("%d\n",max-min);
    }
    return 0;
}

士兵杀敌四

nyoj原题链接


    // 用树状数组写成段更新!!! 
#include<stdio.h>
int num[1000001];int N;
void change(int p,int m)
{
    while(p>0)
    {
        num[p]+=m;
        p-=(p&-p);
    }
}
int query(int n)
{
    int res=0;
    while(n<N)
    {
        res+=num[n];
        n+=(n&-n);
    }
    return res;
}
int main()
{
    int T;
    scanf("%d%d",&T,&N);
    char str[10];int a,b,c;
    while(T--)
    {
        scanf("%s",str);
        if(str[0]=='Q'){
            scanf("%d",&a);printf("%d\n",query(a));
        }
        else{
            scanf("%d%d%d",&a,&b,&c);
            change(a-1,-c);
            change(b,c);
        }
    }
    return 0;
}

士兵杀敌五

nyoj原题链接


#include<stdio.h>
int num[1000001];int N,C,Q;int mi,ni,ai;
int main()
{
    scanf("%d%d%d",&N,&C,&Q);
    while(C--)
    {
        scanf("%d%d%d",&mi,&ni,&ai);
        num[mi-1]-=ai;
        num[ni]+=ai;
    }
    for(int i=N;i>0;i--)
    num[i]+=num[i+1];
    num[0]=0;
    for(int i=1;i<=N;i++)
    {
            num[i]+=num[i-1];
            num[i]%=10003;
    }

    while(Q--)
    {
        int a,b;scanf("%d%d",&a,&b);
        printf("%d\n",(num[b]-num[a-1]+10003)%10003);
    }
    return 0;   
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值