• 【分块】【常数优化】【Orz faebdc】洛谷 P1083 NOIP2012提高组 借教室


    分块90分。 By AutSky_JadeK 【重点在下面】

     1 #include<cstdio>
     2 #include<cmath>
     3 using namespace std;
     4 #define N 1000001
     5 #define INF 2147483647
     6 #define min(a,b) (((a)<(b))?(a):(b))
     7 int n,m,a[N],sum,sz,l[8001],r[8001],minv[8001],delta[8001],num[N],x,y,v;
     8 int ans,re2;
     9 int Res;char C;
    10 inline int G()
    11 {
    12     Res=0;C='*';
    13     while(C<'0'||C>'9')C=getchar();
    14     while(C>='0'&&C<='9'){Res=Res*10+(C-'0');C=getchar();}
    15     return Res;
    16 }
    17 void makeblock()
    18 {
    19     sz=(int)sqrt((double)n*0.1); if(!sz) sz=1;
    20     for(sum=1;sum*sz<n;sum++)
    21       {
    22         l[sum]=r[sum-1]+1; r[sum]=sum*sz;
    23         minv[sum]=INF;
    24         for(int i=l[sum];i<=r[sum];i++) {minv[sum]=min(minv[sum],a[i]); num[i]=sum;}
    25       }
    26     l[sum]=r[sum-1]+1; r[sum]=n;
    27     minv[sum]=INF;
    28     for(int i=l[sum];i<=r[sum];i++) {minv[sum]=min(minv[sum],a[i]); num[i]=sum;}
    29 }
    30 inline void work(const int &L,const int &R)
    31 {
    32     minv[num[L]]=INF;
    33     for(int i=L;i<=R;i++) a[i]-=v;
    34     for(int i=l[num[L]];i<=r[num[L]];i++) minv[num[L]]=min(minv[num[L]],a[i]);
    35 }
    36 inline void update()
    37 {
    38     if(num[x]==num[y]) work(x,y);
    39     else
    40       {
    41         work(x,r[num[x]]); work(l[num[y]],y);
    42         for(int i=num[x]+1;i<num[y];i++) delta[i]-=v;
    43       }
    44 }
    45 inline int query()
    46 {
    47     ans=INF;
    48     if(num[x]==num[y]) {for(int i=x;i<=y;i++) ans=min(ans,a[i]+delta[num[x]]); }
    49     else
    50       {
    51         for(int i=x;i<=r[num[x]];i++) ans=min(ans,a[i]+delta[num[x]]);
    52         for(int i=num[x]+1;i<num[y];i++) ans=min(ans,minv[i]+delta[i]);
    53         for(int i=l[num[y]];i<=y;i++) ans=min(ans,a[i]+delta[num[y]]);
    54       } return ans;
    55 }
    56 int main()
    57 {
    58     n=G(); m=G();
    59     for(int i=1;i<=n;i++) a[i]=G();
    60     makeblock();
    61     for(int i=1;i<=m;i++)
    62       {
    63         v=G(); x=G(); y=G();
    64         if(query()<v)
    65           {
    66             printf("-1
    %d
    ",i);
    67             return 0;
    68           }
    69         else update();
    70       }
    71     puts("0");
    72     return 0;
    73 }

    分块 常数优化 100分。 By faebdc 金牌爷の力Orzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

     1 #include<cstdio>
     2 #include<cmath>
     3 using namespace std;
     4 #define N 1000001
     5 #define INF 2147483647
     6 int n,m,a[N],sum,sz,hf,l[3001],r[3001],minv[3001],delta[3001],num[N],x,y,v;
     7 int ans,re2;
     8 int Res;char C;
     9 inline int G()
    10 {
    11     Res=0;C='*';
    12     while(C<'0'||C>'9')C=getchar();
    13     while(C>='0'&&C<='9'){Res=(Res<<3)+(Res<<1)+C-'0';C=getchar();}
    14     return Res;
    15 }
    16 void makeblock()
    17 {
    18     sz=(int)sqrt((double)n*0.125); if(!sz) sz=1;
    19     hf=sz>>1;
    20     for(sum=1;sum*sz<n;sum++)
    21       {
    22         l[sum]=r[sum-1]+1; r[sum]=sum*sz;
    23         minv[sum]=INF;
    24         for(int i=l[sum];i<=r[sum];i++) {if(minv[sum]>a[i])minv[sum]=a[i]; num[i]=sum;}
    25       }
    26     l[sum]=r[sum-1]+1; r[sum]=n;
    27     minv[sum]=INF;
    28     for(int i=l[sum];i<=r[sum];i++) {if(minv[sum]>a[i])minv[sum]=a[i]; num[i]=sum;}
    29 }
    30 inline void work(const int &L,const int &R)
    31 {
    32     int *t=&(minv[num[L]]);
    33     *t=INF;
    34     int *z;
    35     for(int i=L,*z=a+i;i<=R;i++,z++) {*z-=v;if(*t>*z)*t=*z;}
    36     for(int i=r[num[L]],*z=a+i;i>R;i--,z--) if(*t>*z)*t=*z;
    37     for(int i=l[num[L]],*z=a+i;i<L;i++,z++) if(*t>*z)*t=*z;
    38 }
    39 inline int update()
    40 {
    41     if(num[x]==num[y]) {work(x,y);return minv[num[x]]+delta[num[x]];}
    42         work(x,r[num[x]]); work(l[num[y]],y);
    43         int z;
    44         if(minv[num[x]]+delta[num[x]]>minv[num[y]]+delta[num[y]])
    45             z=minv[num[y]]+delta[num[y]];
    46         else
    47             z=minv[num[x]]+delta[num[x]];
    48         for(int i=num[x]+1;i<num[y];i++) {delta[i]-=v;if(z>minv[i]+delta[i])z=minv[i]+delta[i];}
    49       return z;
    50 }
    51 int main()
    52 {
    53     n=G(); m=G();
    54     for(int i=1;i<=n;i++) a[i]=G();
    55     makeblock();
    56     for(int i=1;i<=m;i++)
    57       {
    58         v=G(); x=G(); y=G();
    59         int z=update();
    60         if(z<0)
    61           {
    62             printf("-1
    %d
    ",i);
    63             return 0;
    64           }
    65       }
    66     puts("0");
    67     return 0;
    68 }
  • 相关阅读:
    c#大文件上传解决方案支持分片断点上传
    css精灵动画
    文字游戏
    利用myeclipse配置数据库连接池
    python 简单的txt文件读写
    数据库连接池配置
    hdu 1030 Delta-wave
    java jdbc sqlhelper
    js实现页面的自动读秒跳转
    购物车模块
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4075340.html
Copyright © 2020-2023  润新知