[bzoj3714] [PA2014]Kuglarz

  这竟然是最小生成树。。哭瞎。

  记前缀和的奇偶性为pre[],要确定一个点的奇偶性,肯定要知道pre[i]和pre[i-1],或者pre[i+1]和pre[i](不一定是直接询问得出的,总之肯定要知道pre[i]

  如果将查询区间[l,r]总和的奇偶性视为一条边(l-1,r)(因为是pre[r]-pre[l-1]),

  要知道所有的pre值,也就是通过连边,使所有的点与0相连通。

  然后就变成mst了。。。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define ll long long
 6 using namespace std;
 7 const int maxn=2023;
 8 int dis[maxn],c[maxn][maxn];
 9 bool u[maxn];
10 ll ans;
11 int i,j,k,n,m;
12  
13 int ra;char rx;
14 inline int read(){
15     rx=getchar(),ra=0;
16     while(rx<'0'||rx>'9')rx=getchar();
17     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
18 }
19 inline void prim(){
20     int mx;register int i;
21     dis[0]=1e9;
22     for(i=1;i<=n;i++)dis[i]=c[0][i];
23     for(int j=1;j<=n;j++){
24         mx=0;for(i=1;i<=n;i++)if(!u[i]&&dis[i]<dis[mx])mx=i;
25 //      printf("mx:%d   dis:%d
",mx,dis[mx]);
26         ans+=dis[mx],u[mx]=1;
27         for(i=1;i<=n;i++)if(!u[i]&&c[mx][i]<dis[i])dis[i]=c[mx][i];
28     }
29 }
30 int main(){
31     n=read();
32     for(i=1;i<=n;i++)for(j=i;j<=n;j++)c[i-1][j]=c[j][i-1]=read();
33     prim();
34     printf("%lld
",ans);
35 }
36 
View Code
原文地址:https://www.cnblogs.com/czllgzmzl/p/5598006.html