#include "dzialka.h" #include "message.h" #include <bits/stdc++.h> using namespace std; #define fru(j,n) for(int j=0; j<(n); ++j) #define tr(it,v) for(auto it=(v).begin(); it!=(v).end(); ++it) #define x first #define y second #define pb push_back #define ALL(G) (G).begin(),(G).end() //#define DEBUG #ifdef DEBUG #define DEB printf #else #define DEB(...) #endif typedef long long LL; typedef pair<int,int> pii; typedef vector<int> vi; int ja,hei,wid,h0,h1,w0,w1; LL teraz; const int MAXN=75005; const int NODES=100; const int BAS=1<<17; vi to_send[NODES]; int E[BAS]; int D[2*BAS]; inline int lepszy(int a, int b){return E[a]<E[b]?a:b;} int get_min(int a,int b){ int ret=lepszy(a,b); a+=BAS; b+=BAS; while(a/2!=b/2){ if((a&1)==0) ret=lepszy(ret,D[a+1]); if((b&1)==1) ret=lepszy(ret,D[b-1]); a>>=1; b>>=1; } return ret; } void go(int a, int b){ if(a>b) return; int p=get_min(a,b); teraz+=1LL*E[p]*(b-p+1)*(p-a+1); go(a,p-1); go(p+1,b); } LL licz(){ teraz=0; for(int i=BAS-1;i;--i) D[i]=lepszy(D[i*2],D[i*2+1]); int last_0=-1; fru(i,wid) if(E[i]==0){ if(last_0+1<i) go(last_0+1,i-1); last_0=i; } go(last_0+1,wid-1); return teraz; } int main(){ fru(i,BAS) D[i+BAS]=i; ja=MyNodeId(); hei=GetFieldHeight(); wid=GetFieldWidth(); int nodes=NumberOfNodes(); assert(0<=ja && ja<nodes); int hj=(hei+nodes-1)/nodes; h0=hj*ja; h1=min(hei,hj*(ja+1)); int wj=(wid+nodes-1)/nodes; w0=wj*ja; w1=min(wid,wj*(ja+1)); for(int c=w0;c<w1;++c){ int q=0; fru(r,hei){ if(IsUsableCell(r,c)) ++q; else q=0; if(r%hj==0) to_send[r/hj].pb(q); } } fru(i,nodes){ tr(it,to_send[i]) PutInt(i,*it); Send(i); } fru(i,nodes) Receive(i); if(h0<h1) fru(i,wid) E[i]=GetInt(i/wj); LL ret=0; for(int r=h0;r<h1;++r){ if(r!=h0){ fru(c,wid) if(IsUsableCell(r,c)) ++E[c]; else E[c]=0; } LL q=licz(); ret+=q; } PutLL(0,ret); Send(0); if(ja==0){ LL wynik=0; fru(i,nodes){ Receive(i); wynik+=GetLL(i); } printf("%lld\n",wynik); } return EXIT_SUCCESS; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | #include "dzialka.h" #include "message.h" #include <bits/stdc++.h> using namespace std; #define fru(j,n) for(int j=0; j<(n); ++j) #define tr(it,v) for(auto it=(v).begin(); it!=(v).end(); ++it) #define x first #define y second #define pb push_back #define ALL(G) (G).begin(),(G).end() //#define DEBUG #ifdef DEBUG #define DEB printf #else #define DEB(...) #endif typedef long long LL; typedef pair<int,int> pii; typedef vector<int> vi; int ja,hei,wid,h0,h1,w0,w1; LL teraz; const int MAXN=75005; const int NODES=100; const int BAS=1<<17; vi to_send[NODES]; int E[BAS]; int D[2*BAS]; inline int lepszy(int a, int b){return E[a]<E[b]?a:b;} int get_min(int a,int b){ int ret=lepszy(a,b); a+=BAS; b+=BAS; while(a/2!=b/2){ if((a&1)==0) ret=lepszy(ret,D[a+1]); if((b&1)==1) ret=lepszy(ret,D[b-1]); a>>=1; b>>=1; } return ret; } void go(int a, int b){ if(a>b) return; int p=get_min(a,b); teraz+=1LL*E[p]*(b-p+1)*(p-a+1); go(a,p-1); go(p+1,b); } LL licz(){ teraz=0; for(int i=BAS-1;i;--i) D[i]=lepszy(D[i*2],D[i*2+1]); int last_0=-1; fru(i,wid) if(E[i]==0){ if(last_0+1<i) go(last_0+1,i-1); last_0=i; } go(last_0+1,wid-1); return teraz; } int main(){ fru(i,BAS) D[i+BAS]=i; ja=MyNodeId(); hei=GetFieldHeight(); wid=GetFieldWidth(); int nodes=NumberOfNodes(); assert(0<=ja && ja<nodes); int hj=(hei+nodes-1)/nodes; h0=hj*ja; h1=min(hei,hj*(ja+1)); int wj=(wid+nodes-1)/nodes; w0=wj*ja; w1=min(wid,wj*(ja+1)); for(int c=w0;c<w1;++c){ int q=0; fru(r,hei){ if(IsUsableCell(r,c)) ++q; else q=0; if(r%hj==0) to_send[r/hj].pb(q); } } fru(i,nodes){ tr(it,to_send[i]) PutInt(i,*it); Send(i); } fru(i,nodes) Receive(i); if(h0<h1) fru(i,wid) E[i]=GetInt(i/wj); LL ret=0; for(int r=h0;r<h1;++r){ if(r!=h0){ fru(c,wid) if(IsUsableCell(r,c)) ++E[c]; else E[c]=0; } LL q=licz(); ret+=q; } PutLL(0,ret); Send(0); if(ja==0){ LL wynik=0; fru(i,nodes){ Receive(i); wynik+=GetLL(i); } printf("%lld\n",wynik); } return EXIT_SUCCESS; } |