zoukankan      html  css  js  c++  java
  • cf406E Hamming Triples (推公式)

    考虑某两行a和b的dis

    如果相同:$|a-b|$

    如果不同:$n-|a-b|$

    然后考虑三行的dis,不妨设a>=b>=c

    那么有4种情况:

    1.a,b,c 0/1的种类相同:$|a-b|+|a-c|+|b-c|=2a-2c$

    2.a和b相同:$2n+2c-2b$

    3.a和c相同:$2n$

    4.b和c相同:$2n+2b-2a$

    所以我们排序后枚举这个b,预处理出前缀和后缀的是0/1的最大值个数、最小值个数以及总共的个数,加一加乘一乘统计答案即可

    注意如果记权值的时候用int,那要先减再加,防爆

     1 #include<bits/stdc++.h>
     2 #define CLR(a,x) memset(a,x,sizeof(a))
     3 using namespace std;
     4 typedef long long ll;
     5 typedef unsigned long long ull;
     6 typedef pair<int,int> pa;
     7 const int maxn=1e5+10,inf=1e9+7;
     8 
     9 inline ll rd(){
    10     ll x=0;char c=getchar();int neg=1;
    11     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    12     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    13     return x*neg;
    14 }
    15 
    16 struct Node{
    17     int v;ll n;
    18     Node(int a=0,ll b=0){v=a,n=b;}
    19 }f[2][maxn][3],g[2][maxn][3],ans;
    20 int N,M;
    21 pa a[maxn];
    22 
    23 inline void update(int v1,ll n1){
    24     // printf("~%d %d
    ",v1,n1);
    25     if(!n1) return;
    26     if(v1>ans.v) ans=Node(v1,n1);
    27     else if(v1==ans.v) ans=Node(v1,n1+ans.n);
    28 }
    29 
    30 int main(){
    31     //freopen("","r",stdin);
    32     int i,j,k;
    33     N=rd(),M=rd();
    34     for(i=1;i<=M;i++){
    35         a[i].second=rd(),a[i].first=rd();
    36     }sort(a+1,a+M+1);
    37     f[0][0][1].v=f[1][0][1].v=g[0][M+1][1].v=g[1][M+1][1].v=inf;
    38     for(i=1;i<=M;i++){
    39         int tp=a[i].second,x=a[i].first;
    40         memcpy(f[!tp][i],f[!tp][i-1],sizeof(f[1][1]));
    41         if(x>f[tp][i-1][0].v) f[tp][i][0]=Node(x,1);
    42         else if(x==f[tp][i-1][0].v) f[tp][i][0]=Node(x,f[tp][i-1][0].n+1);
    43         else f[tp][i][0]=f[tp][i-1][0];
    44         
    45         if(x<f[tp][i-1][1].v) f[tp][i][1]=Node(x,1);
    46         else if(x==f[tp][i-1][1].v) f[tp][i][1]=Node(x,f[tp][i-1][1].n+1);
    47         else f[tp][i][1]=f[tp][i-1][1];
    48         
    49         f[tp][i][2].n=f[tp][i-1][2].n+1;
    50     }
    51     for(i=M;i;i--){
    52         int tp=a[i].second,x=a[i].first;
    53         memcpy(g[!tp][i],g[!tp][i+1],sizeof(g[1][1]));
    54         if(x>g[tp][i+1][0].v) g[tp][i][0]=Node(x,1);
    55         else if(x==g[tp][i+1][0].v) g[tp][i][0]=Node(x,g[tp][i+1][0].n+1);
    56         else g[tp][i][0]=g[tp][i+1][0];
    57         
    58         if(x<g[tp][i+1][1].v) g[tp][i][1]=Node(x,1);
    59         else if(x==g[tp][i+1][1].v) g[tp][i][1]=Node(x,g[tp][i+1][1].n+1);
    60         else g[tp][i][1]=g[tp][i+1][0];
    61         
    62         g[tp][i][2].n=g[tp][i+1][2].n+1;
    63     }
    64     
    65     for(i=2;i<=M-1;i++){
    66         int tp=a[i].second,x=a[i].first;
    67         int v1=2*g[tp][i+1][0].v-2*f[tp][i-1][1].v;ll n1=g[tp][i+1][0].n*f[tp][i-1][1].n;
    68         update(v1,n1);
    69         
    70         v1=2*N-2*x+2*f[!tp][i-1][0].v,n1=f[!tp][i-1][0].n*g[tp][i+1][2].n;
    71         update(v1,n1);
    72         
    73         v1=2*N,n1=f[!tp][i-1][2].n*g[!tp][i+1][2].n;
    74         update(v1,n1);
    75         
    76         v1=2*N-2*g[!tp][i+1][1].v+2*x,n1=f[tp][i-1][2].n*g[!tp][i+1][1].n;
    77         update(v1,n1);
    78     }
    79     printf("%I64d
    ",ans.n);
    80     return 0;
    81 }
  • 相关阅读:
    JavaScript原型链详解
    Js作用域与闭包
    tjs 在嵌套函数中this关键字引用head对象
    NodeJS stream 一:Buffer
    NodeJS Stream 二:什么是 Stream
    NodeJS Stream 三:readable
    NodeJS Stream 四:Writable
    VSS又一次出错了,神出鬼没的
    VS2005的关于母版页嵌套的一个小技巧
    【转】SQL Server数据库开发的二十一条军规
  • 原文地址:https://www.cnblogs.com/Ressed/p/9967561.html
Copyright © 2011-2022 走看看