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\n",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\n",ans.n);
80     return 0;
81 }

 

posted @ 2018-11-16 09:48  Ressed  阅读(308)  评论(0编辑  收藏  举报