zoukankan      html  css  js  c++  java
  • 洛谷10月21日模拟赛解题报告

    ~~考试时太弱,T1+T3一共只拿了暴力分60分,第二题看都没看一眼(其实就是一个二分答案+贪心早知道去做了)~~

    T1:浮游大陆的68号岛

    题目大意就是有n个点,给出每个点到前一个点的距离和每个点的值,然后有m个询问,每次询问从l到r这个区间的每个点到x点的距离*点值的总和模19260817。

    Solution:

    1、首先数据很大,直接暴力的话只能拿到30分到50分(关键看你怎么打暴力),正解其实是前缀和+同余定理(考试时想到了前缀和,但是没有继续深度思考,打了一个前缀和+树状数组其实就是一个暴力)。

    2、首先乘法和加法是满足同余定理的,那么我们可以用两个前缀和数组分别表示到第i个点的距离和到第i个点的要求的值的总和(当然要取模),同理从后往前预处理出两个后缀和,每次查询时只需要用前面到x的值加上后面到x的值取模就好了。时间复杂度O(n),代码量其实很少、思维量也不大,貌似说的不太清楚,去看注释后的代码:

     1 #include<bits/stdc++.h>
     2 #pragma GCC optimize(2)
     3 using namespace std;
     4 #define ll long long
     5 #define il inline
     6 #define mod 19260817
     7 #define maxn 200005
     8 ll n,m,dis[maxn],w[maxn],fall[maxn],ball[maxn],fsum[maxn],bsum[maxn],ans[maxn];
     9 //dis数组存距离,w数组存点值,fall数组存从前往后的距离和,ball数组存从后往前的距离和,fsum存从前往后的权值和,bsum存从后往前的权值和
    10 il ll gi()      //读入优化
    11 {
    12     ll a=0;char x=getchar();bool f=0;
    13     while((x<'0'||x>'9')&&x!='-')x=getchar();
    14     if(x=='-')x=getchar(),f=1;
    15     while(x>='0'&&x<='9')a=a*10+x-48,x=getchar();
    16     return f?-a:a;
    17 }
    18 int main()
    19 {
    20     n=gi(),m=gi();    //下面的4个循环即上面所说的4个数组的预处理
    21     for(int i=1;i<n;i++)dis[i+1]=gi(),dis[i+1]=(dis[i+1]+dis[i])%mod; 
    22     for(int i=1;i<=n;i++)w[i]=gi();
    23     for(int i=2;i<=n;i++)fsum[i]=(fsum[i-1]+dis[i]*w[i]%mod)%mod;
    24     for(int i=n-1;i>=1;i--)bsum[i]=(bsum[i+1]+(dis[n]-dis[i]+mod)*w[i]%mod)%mod;
    25     for(int i=1;i<=n;i++)fall[i]=(w[i]+fall[i-1])%mod;
    26     for(int i=n;i>=1;i--)ball[i]=(ball[i+1]+w[i])%mod;
    27     ll x,l,r;
    28     while(m--)
    29     {
    30         x=gi(),l=gi(),r=gi();   //输出的判断大家模拟一遍应该都能理解,我这里解释一下相减后为什么要+mod,因为对前缀和取模后不一定满足单调性,所以可能出现负值,加上mod便能化解这个问题
    31         if(x<=l)printf("%lld
    ",(fsum[r]-fsum[l-1]+mod-dis[x]*(fall[r]-fall[l-1]+mod)%mod+mod)%mod);
    32         else if(x>=r)printf("%lld
    ",(bsum[l]-bsum[r+1]+mod-(dis[n]-dis[x]+mod)*(ball[l]-ball[r+1]+mod)%mod+mod)%mod);
    33         else printf("%lld
    ",(bsum[l]-bsum[x+1]+mod-(dis[n]-dis[x]+mod)*(ball[l]-ball[x+1]+mod)%mod+mod+fsum[r]-fsum[x-1]+mod-dis[x]*(fall[r]-fall[x-1]+mod)%mod+mod)%mod);
    34     }
    35     return 0;
    36 }

     

  • 相关阅读:
    Test
    占位2
    开坑纪念
    function 类型(函数定义)----读书总结
    css位元素 after
    算法-哈希表
    CF547D
    CF538H
    CF516D
    CF505E
  • 原文地址:https://www.cnblogs.com/five20/p/7711947.html
Copyright © 2011-2022 走看看