zoukankan      html  css  js  c++  java
  • 20180611小测

    T1:

    注意下面的那个求平均值的公式少了一个除大小,自行补上。
    这种数据范围的最小方差生成树?真的可做?
    BZOJ3754那题我可是n^2k暴力卡过去的啊......(好像只能暴力QAQ)
    正解?标算好像就是求尽可能近的区间生成树。显然不对啊......
    不可做,不可做。咕咕咕了。

    T2:

    怎么又是原题?
    真不是BZOJ3505吗?
    考虑枚举所有选三个点的方案再减去三点共线的。
    就是C(n*m,3)-m*C(n,3)-n*C(m,3)-2*sigma(i from 1 to n-1,j from 1 to m-1)(gcd(i,j)-1)(n-i)(m-j)。
    也就是全部的方案数为C(n*m,3),平行于坐标轴三点共线的有m*C(n,3)-n*C(m,3)种,斜向三点共线的,考虑枚举两边的两个点形成的向量,这样的向量存在(n-i)(m-j)个,对于每个向量,把中间点放置在格点上的方案有gcd(i,j)-1种,因为左右两种方向所以要全部*2。
    但是,数据范围什么鬼......
    考虑对公式进行数学变形:

    右边的东西就很容易求和了(具体数学告诉你这样交换求和变量是对的):

    对于gcd反演的惯例反演就是变成phi啦(什么这步你推不出来?丢人!退役吧!)

    (不要吐槽我的公式渲染,msword2016在linux下就是这个德行)
    由于求和式子的取值至于(n-1)/t和(m-1)/t有关,数论分块就很显然了。
    然而卡常只有90分......
    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define debug cout
     6 typedef long long int lli;
     7 using namespace std;
     8 const int maxn=3e6+1e2,lim=3e6;
     9 const int mod=1e9+7,inv[]={0,1,500000004,333333336};
    10 
    11 inline lli C3(lli x) {
    12     lli ret = 1; x %= mod;
    13     for(int i=0;i<3;i++) ret = ret * ( x - i + mod ) % mod , ret = ret * inv[i+1] % mod;
    14     return ret;
    15 }
    16 inline lli LSU(lli x) {
    17     return x * ( x + 1 ) % mod * inv[2] % mod;
    18 }
    19 
    20 lli phi[maxn],phix[maxn],phixx[maxn];
    21 int n,m;
    22 
    23 inline void sieve() {
    24     static int prime[maxn],cnt;
    25     static bool vis[maxn];
    26     phi[1] = 1;
    27     for(int i=2;i<=lim;i++) {
    28         if( !vis[i] ) prime[++cnt] = i , phi[i] = i - 1;
    29         for(int j=1;j<=cnt&&(lli)i*prime[j]<=lim;j++) {
    30             const int tar = i * prime[j];
    31             vis[tar] = 1;
    32             if( i % prime[j] ) phi[tar] = phi[i] * ( prime[j] - 1 );
    33             else { phi[tar] = phi[i] * prime[j]; break; }
    34         }
    35     }
    36     for(int i=1;i<=lim;i++) {
    37         phix[i] = phi[i] * i % mod , phixx[i] = phix[i] * i % mod;
    38         phi[i] = ( phi[i] + phi[i-1] ) % mod , phix[i] = ( phix[i] + phix[i-1] ) % mod , phixx[i] = ( phixx[i] + phixx[i-1] ) % mod;
    39     };
    40 }
    41 
    42 inline lli initans() {
    43     lli ret = ( ( C3((lli)n*m) - n * C3(m) - m * C3(n) ) % mod + mod ) % mod;
    44     ret = ( ret + LSU(n-1) * LSU(m-1) % mod * 2 % mod ) % mod;
    45     return ret;
    46 }
    47 inline lli getsub() { // assert n <= m .
    48     lli ret = 0;
    49     if( n > m ) swap(n,m);
    50     for(int i=1,j;i<n;i=j+1) {
    51         j = min( ( n - 1 ) / ( ( n - 1 ) / i ) , ( m - 1 ) / ( ( m - 1 ) / i ) );
    52         const lli apn = ( n - 1 ) / i , apm = ( m - 1 ) / i;
    53         ret += ( phi[j] - phi[i-1] + mod ) % mod * apn % mod * apm % mod * n % mod * m % mod , ret %= mod;
    54         ret += ( phixx[j] - phixx[i-1] + mod ) % mod * LSU(apn) % mod * LSU(apm) % mod , ret %= mod;
    55         ret -= ( phix[j] - phix[i-1] + mod ) % mod * LSU(apn) % mod * apm % mod * m % mod , ret = ( ret + mod ) % mod;
    56         ret -= ( phix[j] - phix[i-1] + mod ) % mod * LSU(apm) % mod * apn % mod * n % mod , ret = ( ret + mod ) % mod;
    57     }
    58     ret = ret * 2 % mod;
    59     return ret;
    60 }
    61 
    62 int main() {
    63     sieve();
    64     while( scanf("%d%d",&n,&m) == 2 && ( n || m ) ) n++ , m++ , printf("%lld
    ",(initans()-getsub()+mod)%mod);
    65 }
    View Code


    T3:

    这题什么东西啊?真的可做?
    写了一个三分套(线段树+RMQ+三分套二分)(什么鬼),发现不符合单调性,就能过样例,对拍拍一组WA一组。
    无奈写了个O(n^2logn)的暴力,放进去交了,骗了20分......
    正解是这个样子的:

    (表示您并没有告诉我数据随机)
    但是,如果数据真的随机,并没有那么麻烦!
    我可以写一个O(n^2)暴力,从右向左枚举左端点,然后从左向右枚举右端点,对于每个右端点,我么令sj表示当前左端点到j的区间的最小和。显然每次更新的时候sj=min(sj,sj-1,ai-aj),于是就去掉log了。
    这样暴力显然不能AC,我们能加入剪枝,如果当前sj*(n-i)已经<=答案了,我们就可以把内层循环break掉了。
    然后就能AC啦!

    考场20分代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<set>
      6 #define debug cout
      7 typedef long long int lli;
      8 using namespace std;
      9 const int maxn=1e5+1e2,lim=1e5;
     10 const int inf=0x3f3f3f3f , minf = -inf;
     11 const lli lli_inf = 0x3f3f3f3f3f3f3f3fll;
     12 
     13 int in[maxn],n,k;
     14 
     15 namespace Force {
     16     const int maxn=2e3+1e2;
     17     int f[maxn][maxn];
     18     multiset<int> ms;
     19     inline void work() {
     20         lli ans = -lli_inf;
     21         for(int i=1;i<=n;i++) {
     22             ms.clear() , ms.insert(in[i]) , f[i][i] = inf;
     23             for(int j=i+1;j<=n;j++) {
     24                 f[i][j] = f[i][j-1];
     25                 if( ms.find(in[j]) != ms.end() ) { f[i][j] = 0; continue; }
     26                 multiset<int>::iterator it = ms.lower_bound(in[j]);
     27                 if( it != ms.end() ) f[i][j] = min( f[i][j] , *it - in[j] );
     28                 if( it != ms.begin() ) f[i][j] = min( f[i][j] , in[j] - *--it );
     29                 if( j - i + 1 >= k ) ans = max( ans , (lli) f[i][j] * ( j - i ) );
     30                 ms.insert(in[j]);
     31             }
     32         }
     33         printf("%lld
    ",ans);
     34     }
     35 }
     36 namespace Sol {
     37     int Log[maxn],mxl;
     38 
     39     struct RMQ_Min {
     40         int dat[maxn][20];
     41         int& operator [] (const int &x) { return *dat[x]; }
     42         inline void rebuild() {
     43             for(int j=1;j<=mxl;j++) for(int i=1;i<=n;i++) dat[i][j] = min( dat[i][j-1] , dat[i+(1<<(j-1))][j-1] );
     44         }
     45         inline int query(int l,int r) {
     46             int L = Log[r-l+1];
     47             return min( dat[l][L] , dat[r-(1<<L)+1][L] );
     48         }
     49     }rmqmi;
     50 
     51     struct RMQ_Max {
     52         int dat[maxn][20];
     53         int& operator [] (const int &x) { return *dat[x]; }
     54         inline void rebuild() {
     55             for(int j=1;j<=mxl;j++) for(int i=1;i<=n;i++) dat[i][j] = max( dat[i][j-1] , dat[i+(1<<(j-1))][j-1] );
     56         }
     57         inline int query(int l,int r) {
     58             int L = Log[r-l+1];
     59             return max( dat[l][L] , dat[r-(1<<L)+1][L] );
     60         }
     61     }rmqmx;
     62 
     63     struct SemgnetTree_Min {
     64         int l[maxn<<3],r[maxn<<3],lson[maxn<<3],rson[maxn<<3],dat[maxn<<3],cnt;
     65         inline void build(int pos,int ll,int rr) {
     66             l[pos] = ll , r[pos] = rr , dat[pos] = inf;
     67             if( ll == rr ) return;
     68             const int mid = ( ll + rr ) >> 1;
     69             build(lson[pos]=++cnt,ll,mid) , build(rson[pos]=++cnt,mid+1,rr);
     70         }
     71         inline void update(int pos,const int &tar,const int &x) {
     72             if( l[pos] == r[pos] ) return void( dat[pos] = x );
     73             const int mid = ( l[pos] + r[pos] ) >> 1;
     74             tar <= mid ? update(lson[pos],tar,x) : update(rson[pos],tar,x) , dat[pos] = min( dat[lson[pos]] , dat[rson[pos]] );
     75         }
     76         inline int query(int pos,const int &ll,const int &rr) {
     77             if( ll <= l[pos] && r[pos] <= rr ) return dat[pos];
     78             const int mid = ( l[pos] + r[pos] ) >> 1;
     79             if( rr <= mid ) return query(lson[pos],ll,rr);
     80             else if( ll > mid ) return query(rson[pos],ll,rr);
     81             return min( query(lson[pos],ll,rr) , query(rson[pos],ll,rr) );
     82         }
     83         inline void reset() { cnt = 1; }
     84     }sgtmi;
     85 
     86     struct SemgnetTree_Max {
     87         int l[maxn<<3],r[maxn<<3],lson[maxn<<3],rson[maxn<<3],dat[maxn<<3],cnt;
     88         inline void build(int pos,int ll,int rr) {
     89             l[pos] = ll , r[pos] = rr , dat[pos] = minf;
     90             if( ll == rr ) return;
     91             const int mid = ( ll + rr ) >> 1;
     92             build(lson[pos]=++cnt,ll,mid) , build(rson[pos]=++cnt,mid+1,rr);
     93         }
     94         inline void update(int pos,const int &tar,const int &x) {
     95             if( l[pos] == r[pos] ) return void( dat[pos] = x );
     96             const int mid = ( l[pos] + r[pos] ) >> 1;
     97             tar <= mid ? update(lson[pos],tar,x) : update(rson[pos],tar,x) , dat[pos] = max( dat[lson[pos]] , dat[rson[pos]] );
     98         }
     99         inline int query(int pos,const int &ll,const int &rr) {
    100             if( ll <= l[pos] && r[pos] <= rr ) return dat[pos];
    101             const int mid = ( l[pos] + r[pos] ) >> 1;
    102             if( rr <= mid ) return query(lson[pos],ll,rr);
    103             else if( ll > mid ) return query(rson[pos],ll,rr);
    104             return max( query(lson[pos],ll,rr) , query(rson[pos],ll,rr) );
    105         }
    106         inline void reset() { cnt = 1; }
    107     }sgtmx;
    108 
    109     int liml[maxn],limr[maxn];
    110 
    111     inline bool judge(int l,int r) {
    112         int ll = rmqmx.query(l,r) , rr = rmqmi.query(l,r);
    113         return ll <= l && r <= rr;
    114     }
    115     inline int binrit(int curl,int l,int r) {
    116         if( judge(curl,r) ) return r;
    117         int mid;
    118         while( r > l + 1 ) {
    119             mid = ( l + r ) >> 1;
    120             if( judge(curl,mid) ) l = mid;
    121             else r = mid;
    122         }
    123         return l;
    124     }
    125     inline int triseg(int pos) { // if same move l .
    126         int l = liml[pos] , r = pos , lmid , rmid , tpl;
    127         int cl , cr , ret = -inf;
    128         while( r > l + 2 ) {
    129             lmid = ( l + l + r ) / 3 , rmid = ( l + r + r ) / 3;
    130 
    131             tpl = rmqmi.query(lmid,pos);
    132             if( tpl < pos ) cl = -inf;
    133             else cl = binrit(lmid,pos,limr[pos]) - lmid;
    134 
    135             tpl = rmqmi.query(rmid,pos);
    136             if( tpl < pos ) cr = -inf;
    137             else cr = binrit(rmid,pos,limr[pos]) - rmid;
    138 
    139             if( cl <= cr ) l = lmid;
    140             else r = rmid;
    141         }
    142         for(int i=l;i<=r;i++) {
    143             tpl = rmqmi.query(i,pos);
    144             if( tpl < pos ) continue;
    145             ret = max( ret , binrit(i,pos,limr[pos]) - i );
    146         }
    147         return ret;
    148     }
    149     inline int getmxseg(int lim) {
    150         int ret = -inf;
    151         sgtmi.reset() , sgtmi.build(1,1,1e5);
    152         for(int i=n;i;i--) limr[i] = rmqmi[i] = min(sgtmi.query(1,in[i]-lim+1,in[i]+lim-1)-1,n) , sgtmi.update(1,in[i],i);
    153         sgtmx.reset() , sgtmx.build(1,1,1e5);
    154         for(int i=1;i<=n;i++) liml[i] = rmqmx[i] = max(sgtmx.query(1,in[i]-lim+1,in[i]+lim-1)+1,1) , sgtmx.update(1,in[i],i);
    155         rmqmi.rebuild() , rmqmx.rebuild();
    156         for(int i=1;i<=n;i++) {
    157             ret = max( ret , triseg(i) );
    158         }
    159         return ret >= k ? ret : -inf;
    160     }
    161     inline lli tri1() { // WAWAWA
    162         int l = 1 , r = lim , lmid , rmid;
    163         lli cl , cr , ret = -lli_inf;
    164         while( r > l + 2 ) {
    165             lmid = ( l + l + r ) / 3 , rmid = ( l + r + r ) / 3;
    166             cl = (lli) lmid * getmxseg(lmid) , cr = (lli) rmid * getmxseg(rmid);
    167             if( cl <= cr ) l = lmid;
    168             else r = rmid;
    169         }
    170         for(int i=l;i<=r;i++) ret = max( ret , (lli) i * getmxseg(i) );
    171         return ret;
    172     }
    173     inline lli tri2() { // WAWAWA
    174         int l = 1 , r = lim , lmid , rmid;
    175         lli cl , cr , ret = -lli_inf;
    176         while( r > l + 2 ) {
    177             lmid = ( l + l + r ) / 3 , rmid = ( l + r + r ) / 3;
    178             cl = (lli) lmid * getmxseg(lmid) , cr = (lli) rmid * getmxseg(rmid);
    179             if( cl < cr ) l = lmid;
    180             else r = rmid;
    181         }
    182         for(int i=l;i<=r;i++) ret = max( ret , (lli) i * getmxseg(i) );
    183         return ret;
    184     }
    185 
    186     inline void getlog() {
    187         for(int i=2;i<=n;i++) Log[i] = Log[i>>1] + 1;
    188         mxl = Log[n];
    189     }
    190 
    191     inline void work() {
    192         --k , getlog() , printf("%lld
    ",max(tri1(),tri2()));
    193     }
    194 }
    195 
    196 int main() {
    197     static int T;
    198     scanf("%d",&T);
    199     while(T--) {
    200         scanf("%d%d",&n,&k);
    201         for(int i=1;i<=n;i++) scanf("%d",in+i);
    202         if( n <= 3e3 ) Force::work();
    203         else Sol::work();
    204     }
    205     return 0;
    206 }
    View Code

    正解代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cstdlib>
     6 #define debug cout
     7 typedef long long int lli;
     8 using namespace std;
     9 const int maxn=1e5+1e2,lim=1e5,blk=1e3;
    10 const int inf=0x3f3f3f3f , minf = -inf;
    11 const lli lli_inf = 0x3f3f3f3f3f3f3f3fll;
    12 
    13 int in[maxn],n,k;
    14 
    15 namespace Force {
    16     int s[maxn];
    17     inline void work() {
    18         lli ans = -lli_inf;
    19         memset(s,0x3f,sizeof(s));
    20         for(int i=n;i;i--) {
    21             for(int j=i+1;j<=n/*&&j<=i+blk*/;j++) {
    22                 s[j] = min( s[j] , abs(in[i]-in[j]) ) , s[j] = min( s[j] , s[j-1] );
    23                 if( j - i >= k )ans = max( ans , (lli) s[j] * ( j - i ) );
    24                 if( (lli) s[j] * ( n - i ) <= ans ) break;
    25             }
    26         }
    27         printf("%lld
    ",ans);
    28     }
    29 }
    30 
    31 int main() {
    32     static int T;
    33     scanf("%d",&T);
    34     while(T--) {
    35         scanf("%d%d",&n,&k) , --k;
    36         for(int i=1;i<=n;i++) scanf("%d",in+i);
    37         Force::work();
    38     }
    39 }
    View Code


    这种题都做不出来,果然还是我太菜啦!
    对了我决定把电脑里的Win10删掉以彻底杜绝自己想要推gal的思想

    冷(つめ)たかった 寂(さみ)しかった
    好冷啊,好寂寞
    凍(い)てつく街(まち)に息衝(いきづ)く
    生活在这冰封的城镇里
    優(やさ)しい愛(あい)の唄(うた)が
    温柔地爱的歌谣
    胸(むね)の奥(おく)積(つ)もって
    在心中回响
    変わる景色 幼い私 隔てた 境界線(きょうかいせん
    将变化的景色和幼小的自己分隔的境界线
    見(み)えなくなるくらい 染(そ)めていたの
    变得不再那样清晰

  • 相关阅读:
    linux父子进程问题
    Raft协议--中文论文介绍
    adb、pm命令操作apk包
    gradle配置
    命令行 更新Android sdk
    Gradle 脚本剪片---copy
    Java数组,去掉重复值、增加、删除数组元素
    注解Annotation 详解(转)
    MAC自带的SVN进行升级
    Android Studio 简单功能介绍
  • 原文地址:https://www.cnblogs.com/Cmd2001/p/9167789.html
Copyright © 2011-2022 走看看