这里必须标记一下那个傻逼问题,再不解决我人就没了!
先放一个 $T3$ $20$ 分暴力
1 #include<bits/stdc++.h> 2 #define rep(i,x,y) for(int i=(x);i<=(y);++i) 3 #define dwn(i,x,y) for(int i=(x);i>=(y);--i) 4 #define rep_e(i,u) for(int i=hd[u];i;i=e[i].nxt) 5 #define lc tr[o].l 6 #define rc tr[o].r 7 #define N 100003 8 #define inf 2147483647 9 using namespace std; 10 inline int read(){ 11 int x=0; bool f=1; char c=getchar(); 12 for(;!isdigit(c);c=getchar()) if(c=='-') f=0; 13 for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0'); 14 if(f) return x; 15 return 0-x; 16 } 17 18 int T1_ROOT=1; 19 int n,m,L1,R1,L2,R2,W,ans; 20 21 struct edge{int u,v,w;}e[2002*2002]; 22 int cnt; 23 inline bool cmp(edge a,edge b){return a.w<b.w;} 24 25 struct Tree{int l,r,v;}tr[N*150]; 26 int rt[N<<1],tot[3]; 27 inline int newNode(int x){return ++tot[x];} 28 inline void pushdown(int o){ 29 if(tr[o].v){ 30 tr[lc].v+=tr[o].v, tr[rc].v+=tr[o].v; 31 tr[o].v=0; 32 } 33 } 34 void add2(int &o,int l,int r){ 35 if(!o) o=newNode(2); 36 if(L2<=l && r<=R2){tr[o].v+=W; return;} 37 pushdown(o); 38 int mid=(l+r)>>1; 39 if(L2<=mid) add2(lc,l,mid); 40 if(R2>mid) add2(rc,mid+1,r); 41 } 42 void add1(int &o,int l,int r){ 43 if(!o) o=newNode(1); 44 //printf("%d %d %d %d %d\n",o,l,r,L1,R1); 45 //system("pause"); 46 if(L1<=l && r<=R1){add2(rt[o],1,n); return;} 47 int mid=(l+r)>>1; 48 if(L1<=mid) add1(lc,l,mid); 49 if(R1>mid) add1(rc,mid+1,r); 50 } 51 int X,mat[2002][2002]; 52 void dfs2(int o,int l,int r){ 53 if(!o) return; 54 if(l==r){mat[X][l]+=tr[o].v; return;} 55 pushdown(o); 56 int mid=(l+r)>>1; 57 dfs2(lc,l,mid); 58 dfs2(rc,mid+1,r); 59 } 60 void dfs1(int o,int l,int r){ 61 if(!o) return; 62 rep(i,l,r) X=i, dfs2(rt[o],1,n); 63 if(l==r) return; 64 int mid=(l+r)>>1; 65 dfs1(lc,l,mid); 66 dfs1(rc,mid+1,r); 67 } 68 /* 69 struct SegTree{ 70 struct TREE{int l,r,v;}tr[N*90]; 71 int L,R,W,e[2001][2001]; 72 73 inline void pushdown(int o){ 74 if(tr[o].v){ 75 tr[lc].v+=tr[o].v, tr[rc].v+=tr[o].v; 76 tr[o].v=0; 77 } 78 } 79 void add(int &o,int l,int r){ 80 if(!o) o=newNode(1); 81 if(L1<=l && r<=R1){tr[o].v+=W; return;} 82 pushdown(o); 83 int mid=(l+r)>>1; 84 if(L1<=mid) add1(lc,l,mid); 85 if(R1>mid) add1(rc,mid+1,r); 86 } 87 inline void add(int ver,int l,int r,int w){ 88 L=l, R=r, W=w; add(rt[ver],1,n); 89 } 90 } 91 */ 92 int fa[N]; 93 int find(int x){return x==fa[x] ? x : fa[x]=find(fa[x]);} 94 namespace pts20{ 95 void solve(){ 96 rep(i,1,m) 97 L1=read(), R1=read(), L2=read(), R2=read(), W=read(), add1(T1_ROOT,1,n); 98 dfs1(1,1,n); 99 rep(i,1,n) 100 rep(j,i+1,n) 101 e[cnt++]=(edge){i,j,mat[i][j]}; 102 sort(e,e+cnt,cmp); 103 rep(i,1,n) fa[i]=i; 104 int e_cnt; 105 for(int i=0;i<cnt;++i){ 106 int fu=find(e[i].u), fv=find(e[i].v); 107 //printf("zuixiao:%d %d %d\n",e[i].u,e[i].v,e[i].w); 108 if(fu==fv) continue; 109 fa[fv]=fu; 110 ans+=e[i].w; 111 ++e_cnt; 112 //printf("%d %d %d %d\n",e_cnt,n-1,i,cnt); 113 if(e_cnt>=n-1) break; 114 } 115 printf("%d\n",ans); 116 } 117 } 118 using namespace pts20; 119 /* 120 int mn_o,mn_v; 121 void queryMin(int o,int l,int r){ 122 if(!o) return; 123 if(l==r){mn_o=o, mn_v=tr[o].mn; return;} 124 int mid=(l+r)>>1; 125 if(tr[lc].mn<=tr[rc].mn) queryMin(lc,l,mid); 126 else queryMin(rc,mid+1,r); 127 } 128 int blo; 129 */ 130 int main(){ 131 //freopen("C.in","r",stdin); 132 //freopen("C.out","w",stdout); 133 n=read(), m=read(); 134 tot[1]=1, tot[2]=n<<1; 135 if(n<=2000) pts20::solve(); 136 return 0; 137 } 138 /* 139 5 4 140 1 2 3 4 10 141 1 1 2 2 -20 142 3 3 4 4 -5 143 2 2 5 5 -15 144 */