B
4D"部分和"问题,相当于2D部分和的拓展,我是分解成2D部分和做的:
f[x1][y1][x2][y2]=true/false 表示 左上(x1,y1) 右下(x2,y2)的矩形是否是good rectangle;
p1[][]x][y]表示右下为(x,y)的good rectangle有多少个,相当于一个[x][y]确定的2D前缀和;
t[i][j][x][y]表示左上在矩形 (i,j) (x,y) 区域内 右下确定为(x,y)的方案数有多少个,可以o(1)计算:
t[i][j][x][y]=p1[x][y][x][y]-
p1[i-1][y][x][y]-
p1[x][j-1][x][y]+
p1[i-1][j-1][x][y];
p2[x1][y1][x2][y2] 表示询问(x1,y1) (x2,y2) , 它恰好就是t[x1][y1][][] 在(x1,y1)确定下的2D前缀和.
1 void init() 2 { 3 for (int i=1 ; i<=n ; i++ ) 4 for (int j=1 ; j<=m ; j++ ) sum[i][j]=s[i][j]=='1'?1:0; 5 for (int i=1 ; i<=n ; i++ ) 6 for (int j=1 ; j<=m ; j++ ) sum[i][j]=sum[i][j-1]+sum[i][j]; 7 for (int i=1 ; i<=m ; i++ ) 8 for (int j=1 ; j<=n ; j++ ) sum[j][i]=sum[j-1][i]+sum[j][i]; 9 10 for (int x=1 ; x<=n ; x++ ) 11 for (int y=1 ; y<=m ; y++ ) 12 for (int i=1 ; i<=x ; i++ ) 13 for (int j=1 ; j<=y ; j++ ) 14 if (check(i,j,x,y)) f[i][j][x][y]=1; 15 16 for (int x=1 ; x<=n ; x++ ) 17 for (int y=1 ; y<=m ; y++ ) 18 { 19 for (int i=1 ; i<=x ; i++ ) 20 for (int j=1 ; j<=y ; j++ ) 21 p1[i][j][x][y] = p1[i][j-1][x][y]+f[i][j][x][y]; 22 for (int i=1 ; i<=y ; i++ ) 23 for (int j=1 ; j<=x ; j++ ) 24 p1[j][i][x][y] = p1[j-1][i][x][y]+p1[j][i][x][y]; 25 } 26 for (int x=1 ; x<=n ; x++ ) 27 for (int y=1 ; y<=m ; y++ ) 28 { 29 for (int i=x ; i<=n ; i++ ) 30 for (int j=y ; j<=m ; j++ ) 31 p2[x][y][i][j] = p2[x][y][i][j-1] + getvar(x,y,i,j); 32 for (int i=y ; i<=m ; i++ ) 33 for (int j=x ; j<=n ; j++ ) 34 p2[x][y][j][i] = p2[x][y][j-1][i] + p2[x][y][j][i]; 35 } 36 }
C
题目描述有点绕啊,原来d是最多单位时间走d步的意思, 不是每步走d...
总之最后问题转化成区间最值问题,好在询问区间每次只有头尾不同,可以用单调队列优化.
D
解决问题的关键是插入或删除一个点的同时维护连通块大小.
先考虑一个静态的问题:对于给定的集合求size.
如果按dfs序考虑,ans*2 = sigma(dist(order,order+1)) + dist(first,end)。
现在动态考虑,如果插入的点i在u,v中间:
add = dist(u,i) + dist(i,v) - dist(u,v)
可以理解为,新增的代价是连接u,i的代价+连接i,v的代价,但要此前u,v已经连接了,所以要减去加入前连接(u,v)的代价.
另外两种可能是:
u不存在和v不存在,那么add = dist(*,i) ( *表示u或者v);
删除可以类似考虑.
最后,问题转化为,动态求集合中比order[i]小的最大值和比order[i]大的最小值,用set或者树状数组都可以解决.
1 #define maxn 100010 2 vector<int>e[maxn]; 3 int n,k,sz,dep[maxn],bit[maxn<<1|1], 4 first[maxn],rmq[25][maxn<<1|1],t; 5 6 void dfs(int cur,int fa) 7 { 8 rmq[0][++t]=cur; 9 first[cur]=t; 10 rep(i,(int)e[cur].size()) if(e[cur][i]!=fa) 11 { 12 dep[e[cur][i]]=dep[cur]+1; 13 dfs(e[cur][i],cur); 14 rmq[0][++t]=cur; 15 } 16 } 17 void initrmq() 18 { 19 for (int i=1 ; (1<<i)<=t ; i++ ) 20 for (int j=1 ; j+(1<<i)-1<=t ; j++ ) 21 { 22 int a=rmq[i-1][j]; 23 int b=rmq[i-1][j+(1<<(i-1))]; 24 if (dep[a]<dep[b]) rmq[i][j]=a; 25 else rmq[i][j]=b; 26 } 27 } 28 int lca(int a,int b) 29 { 30 assert(a && b); 31 int l,r,len=0; 32 l = min(first[a],first[b]); 33 r = max(first[a],first[b]); 34 while (1<<(len+1)<=(r-l+1)) len++; 35 if (dep[rmq[len][l]]<dep[rmq[len][r-(1<<len)+1]]) 36 return rmq[len][l]; 37 else return rmq[len][r-(1<<len)+1]; 38 } 39 int lowbit(int x) {return x&(-x);} 40 void ins(int x,int var) 41 { 42 for (int i=x ; i<=t ; i+=lowbit(i)) bit[i]+=var; 43 } 44 int query(int x) 45 { 46 int res=0; 47 for (int i=x ; i>0 ; i-=lowbit(i)) res+=bit[i]; 48 return res; 49 } 50 int range_sum(int l,int r){return query(r)-query(l-1);} 51 int binsearchr(int l,int r) 52 { 53 while (l<=r) 54 { 55 if (range_sum(mid,r)) l=mid; 56 else r=mid-1; 57 if (l+1>=r) 58 { 59 if (range_sum(r,r)) return r; 60 if (range_sum(l,l)) return l; 61 return 0; 62 } 63 } 64 return 0; 65 } 66 int binsearchl(int l,int r) 67 { 68 while (l<=r) 69 { 70 if (range_sum(l,mid)) r=mid; 71 else l=mid+1; 72 if (l+1>=r) 73 { 74 if (range_sum(l,l)) return l; 75 if (range_sum(r,r)) return r; 76 return 0; 77 } 78 } 79 return 0; 80 } 81 int getdist(int u,int v) { return dep[u]+dep[v]-2*dep[lca(u,v)]; } 82 int getsize() 83 { 84 int l = rmq[0][binsearchl(1,t)]; 85 int r = rmq[0][binsearchr(1,t)]; 86 assert(l && r); 87 int v = getdist(l,r); 88 return sz + v; 89 } 90 void add(int x) 91 { 92 int dfst = first[x]; 93 int l = rmq[0][binsearchr(1,dfst-1)]; 94 int r = rmq[0][binsearchl(dfst+1,t)]; 95 int v = 0; 96 if (l) v += getdist(x,l); 97 if (r) v += getdist(x,r); 98 if (l && r) v -= getdist(l,r); 99 sz += v; 100 ins(dfst,1); 101 } 102 void del(int x) 103 { 104 int dfst = first[x]; 105 int l = rmq[0][binsearchr(1,dfst-1)]; 106 int r = rmq[0][binsearchl(dfst+1,t)]; 107 int v = 0; 108 if (l) v += getdist(x,l); 109 if (r) v += getdist(x,r); 110 if (l && r) v -= getdist(l,r); 111 sz -= v; 112 ins(dfst,-1); 113 114 } 115 int main() 116 { 117 // freopen("test.txt","r",stdin); 118 scanf("%d%d",&n,&k); 119 for (int i=1 ; i<n ; i++ ) 120 { 121 int u,v; 122 scanf("%d%d",&u,&v); 123 e[u].push_back(v); 124 e[v].push_back(u); 125 } 126 dfs(1,0); 127 initrmq(); 128 int ans=1; 129 for (int l=1,i=1 ; i<=n ; i++ ) 130 { 131 add(i); 132 while (getsize()>(k-1)*2) del(l++); 133 ans = max(i-l+1,ans); 134 } 135 printf("%d\n",ans); 136 return 0; 137 }
E
(反演。。。不会T-T)