洛谷10月月赛R2·浴谷八连测R3 -Chtholly-

来源:互联网 发布:魅思cms视频系统 编辑:程序博客网 时间:2024/06/05 00:11

T1 浮游大陆的68号岛
T2 Chtholly Nota Seniorious
T1
这个题还是比较简单的,毕竟是第一题。
首先,不要想复杂的数据结构,因为中间没有修改值,蒟蒻就是因为高大上的数据结构不精通,所以没有走弯路喽。

用一个前缀和来记录储物点的物件数目;
dis数组记录到1点的距离;
cost数组记录前i个储物点的物品都搬到1点的花费。
接下来就是模拟了。
分为三种情况
x<=l,ans=(cost[r]-cost[l-1])-dis[x]*(sum[r]-sum[l-1]);用都搬到1点的花费减去每个物品从x点到1点的花费,就是答案了。
x>=r;
l< x< r;
后面这两种与前面类似。

注意取摸,如果变为负数,就+mod再%mod(这一点蒟蒻细心地想到了QAQ)

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#define LL long longusing namespace std;const int MOD=19260817;const int N=200009;LL a[N],sum[N],dis[N],cost[N],ans; int n,m;int main(){    scanf("%d%d",&n,&m);    for(int i=2;i<=n;i++) scanf("%lld",&dis[i]),(dis[i]+=dis[i-1])%=MOD;    for(int i=1;i<=n;i++)     {        scanf("%lld",&a[i]);        sum[i]=(sum[i-1]+a[i])%MOD;        cost[i]=(cost[i-1]+a[i]*dis[i]%MOD)%MOD;    }    for(int i=1;i<=m;i++)    {        ans=0;        int x,l,r;        scanf("%d%d%d",&x,&l,&r);        if(x<=l)        {            ans=((cost[r]-cost[l-1]+MOD)%MOD-(dis[x]*(sum[r]-sum[l-1]+MOD))%MOD+MOD)%MOD;        }        else        if(x>=r)        {            ans=(dis[x]*(sum[r]-sum[l-1]+MOD)%MOD-(cost[r]-cost[l-1]+MOD)%MOD+MOD)%MOD;        }        else        if(x<r&&x>l)        {            ans=(dis[x]*(sum[x]-sum[l-1]+MOD)%MOD-(cost[x]-cost[l-1]+MOD)%MOD+MOD)%MOD;            ans+=((cost[r]-cost[x]+MOD)%MOD-dis[x]*(sum[r]-sum[x]+MOD)%MOD+MOD)%MOD;            ans=ans%MOD;        }        printf("%lld\n",ans);    }    return 0;} 

T2
二分+贪心+矩阵旋转
先把矩阵存四遍,旋转的四个。
显然,肯定把最大值和最小值放到不同的两部分。
那么把四个矩阵,从左上角一行一行地拓展第一部分,右下角一行一行地拓展第二部分。
左上角的条件我们设为a[i][j]< minn+x,右下角的条件设为a[i][j]>maxn-x.
拓展时,采用贪心的策略,左上角的只要满足条件且比上一行的短或相同,就一直拓展(不超过上一行是因为要满足只拐一次弯)
右下角亦然。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#define LL long longusing namespace std;const int N=2009;const int inf=2e9+100;int n,m,maxn,minn=inf;int a[4][N][N],en[N];void init(){    int x;    scanf("%d%d",&n,&m);    int x1=m,y1=1,x2=n,y2=m,x3=1,y3=n;    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        {            scanf("%d",&x);            a[0][i][j]=x;            a[1][x1--][y1]=x;            a[2][x2][y2--]=x;            a[3][x3++][y3]=x;            minn=min(minn,x);            maxn=max(maxn,x);        }        y1++;x1=m;        x2--;y2=m;        y3--;x3=1;//旋转存4个矩阵     }}bool check_map(int k,int x){    memset(en,0,sizeof(en));    int nn=n,mm=m;    if(k&1) swap(nn,mm);    en[0]=mm+1;    int i,j;    for(i=1;i<=nn;i++)    {        for(j=1;j<en[i-1];j++)//小于等于上一行        {            if(a[k][i][j]<=minn+x) continue;            else break;        }         en[i]=j;    }    for(i=nn;i>=1;i--)    {        for(j=mm;j>=en[i];j--)        {            if(a[k][i][j]>=maxn-x) continue;            else return 0;        }    }    return 1;}bool check(int x){    if(check_map(0,x)) return 1;    if(check_map(1,x)) return 1;    if(check_map(2,x)) return 1;    if(check_map(3,x)) return 1;    return 0;}int main(){    //freopen("sample.in","r",stdin);    init();    int L=0,R=maxn-minn,mid;    while(L<=R)    {        mid=(L+R)>>1;        if(check(mid)) R=mid-1;        else L=mid+1;    }    printf("%d",L);    return 0;}
原创粉丝点击