A. Cakey McCakeFace

按题意模拟即可。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 0, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
int n, m;
int a[2005], b[2005];
int main()
{
while(~scanf("%d%d",&n, &m))
{
for(int i = 1; i <= n; ++i)
{
scanf("%d", &a[i]);
}
for(int i = 1; i <= m; ++i)
{
scanf("%d", &b[i]);
}
map<int,int>mop;
int cnt = -1, val;
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= m; ++j)if(b[j] >= a[i])
{
++mop[b[j] - a[i]];
}
}
for(auto it : mop)
{
if(it.second > cnt)
{
cnt = it.second;
val = it.first;
}
}
printf("%d\n", val);
}
return 0;
} /*
【trick&&吐槽】 【题意】 【分析】 【时间复杂度&&优化】 */

  

B. Table

枚举下底边,求出每个位置向上延伸的最大长度,枚举每个位置作为右下角,那么单调栈中每一个子矩形都可以对长宽都不超过它的询问产生贡献,通过差分二维前缀和,那么$O(1)$单点修改即可。

为了避免枚举单调栈中每一项,可以在每一项退栈时计算有多少个右下角可以与它产生贡献,这是对差分后的二维前缀和的一段区间加,再次差分前缀和转化成单点修改即可。

时间复杂度$O(xy+n+d)$。

#include<cstdio>
const int N=2010;
int n,m,_a,_b,i,j,a[N][N],b[N][N],f[N],q[N],t;
inline void work(int x,int y,int z,int o){
/*for(int i=y;i<=z;i++){
b[i-y][o]--;
b[i+1-x][o]++;
}
return;*/
b[0][o]--;
b[z-y+1][o]++;
b[y+1-x][o]++;
b[z+1-x+1][o]--;
}
int main(){
scanf("%d%d%d%d",&n,&m,&_a,&_b);
while(_a--){
int xl,xr,yl,yr;
scanf("%d%d%d%d",&xl,&xr,&yl,&yr);
a[xr][yr]++;
a[xl][yr]--;
a[xr][yl]--;
a[xl][yl]++;
}
for(i=n;i;i--)for(j=m;j;j--)a[i][j]+=a[i+1][j]+a[i][j+1]-a[i+1][j+1];
for(i=1;i<=n;i++)for(j=1;j<=m;j++)a[i][j]=a[i][j]==0; /*puts("");
for(i=1;i<=n;i++){
for(j=1;j<=m;j++)printf("%d",a[i][j]);
puts("");
}*/ for(i=1;i<=n;i++){
for(j=1;j<=m;j++)if(a[i][j])f[j]++;else f[j]=0;
for(q[t=0]=0,j=1;j<=m;q[++t]=j++){
while(t&&f[j]<f[q[t]]){
work(q[t-1]+1,q[t],j-1,f[q[t]]);
t--;
}
}
for(j=1;j<=t;j++)work(q[j-1]+1,q[j],m,f[q[j]]);
}
for(j=1;j<=n;j++)for(i=1;i<=m+5;i++)b[i][j]+=b[i-1][j];
for(i=m;i;i--)for(j=n;j;j--)b[i][j]+=b[i+1][j]+b[i][j+1]-b[i+1][j+1];
while(_b--)scanf("%d%d",&i,&j),printf("%d\n",b[j][i]);
}
/*
7 5 3 9
1 2 0 1
5 7 2 5
0 1 2 4
7 1
3 5
5 3
2 2
3 3
4 4
4 5
6 2
1 1
*/

  

C. Macarons

设$f[i][S]$表示考虑前$i$行,第$i$行每个位置是否被填充的情况为$S$的合法方案数。

逐格转移预处理出转移矩阵后快速幂即可。

时间复杂度$O(2^{3n}\log m)$。

#include<cstdio>
#define rep(i) for(int i=0;i<m;i++)
typedef long long ll;
const int N=260,P=1000000000;
int n,m,S,i,j,k,x,y,z,f[N],g[N];
ll K;
int A[N][N],B[N][N],C[N][N];
inline void up(int&a,int b){a=a+b<P?a+b:a+b-P;}
inline void mul(int A[][N],int B[][N],int F[][N]){
rep(i)rep(j)C[i][j]=0;
rep(i)rep(j)if(A[i][j])rep(k)if(B[j][k])C[i][k]=(1LL*A[i][j]*B[j][k]+C[i][k])%P;
rep(i)rep(j)F[i][j]=C[i][j];
}
int main(){
scanf("%d%lld",&n,&K);
m=1<<n;
for(S=0;S<m;S++){
for(j=0;j<m;j++)f[j]=g[j]=0;
f[S]=1;
for(i=0;i<n;i++){
for(j=0;j<m;j++)g[j]=0;
for(j=0;j<m;j++)if(f[j]){
if(!(j>>i&1)){
up(g[j^(1<<i)],f[j]);
}else{
up(g[j^(1<<i)],f[j]);
up(g[j],f[j]);
if(i&&!(j>>(i-1)&1))up(g[j|(1<<(i-1))],f[j]);
}
}
for(j=0;j<m;j++)f[j]=g[j];
}
for(j=0;j<m;j++)A[j][S]=f[j];
}
for(i=0;i<m;i++)B[i][i]=1;
for(;K;K>>=1,mul(A,A,A))if(K&1)mul(A,B,B);
printf("%d",B[m-1][m-1]);
}

  

D. Candy Chain

设$f[i][j]$表示将区间$[i,j]$全部消完的最大收益,$dp[i]$表示考虑前$i$个位置的最大收益,那么$dp[i]=\max(dp[i-1],dp[j-1]+f[j][i](1\leq j\leq i))$。

对于$f$的计算,设$g[i][j][k]$表示考虑区间$[i,j]$,最后一次要删去的串在字典树上位于$k$点的最大收益,要么枚举一个区间消掉,要么在字典树上往下走,要么消去$k$代表的字符串。

时间复杂度$O(n^4c)$,但常数很小,且无用状态很多,远远达不到上界。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=55,M=20005;
int n,m,i,j,k,x,tot,son[M][26],w[M],f[N][N],dp[N];
int g[N][M];
char a[N],b[N];
inline void up(int&a,int b){a<b?(a=b):0;}
inline void ins(int l,int v){
int x=0;
for(int i=0;i<l;i++){
int o=b[i]-'a';
if(!son[x][o])son[x][o]=++tot;
x=son[x][o];
}
up(w[x],v);
}
int main(){
for(i=1;i<M;i++)w[i]=-1;
scanf("%s",a+1);
n=strlen(a+1);
for(i=1;i<=n;i++)a[i]-='a';
scanf("%d",&m);
while(m--){
int l,w;
scanf("%s%d",b,&w);
l=strlen(b);
ins(l,w);
reverse(b,b+l);
ins(l,w);
}
for(i=0;i<=n+1;i++)for(j=0;j<=n+1;j++)f[i][j]=-1; for(i=n;i;i--){
for(j=i-1;j<=n+1;j++)for(k=0;k<=tot;k++)g[j][k]=-1;
g[i-1][0]=0;
for(j=i-1;j<=n;j++)for(k=0;k<=tot;k++)if(~g[j][k]){
for(x=j+1;x<=n;x++)if(~f[j+1][x])up(g[x][k],g[j][k]+f[j+1][x]);
if(j<n){
int y=son[k][a[j+1]];
if(y){
up(g[j+1][y],g[j][k]);
if(~w[y])up(g[j+1][0],g[j][k]+w[y]);
}
}
if(k==0)up(f[i][j],g[j][k]);
}
} for(i=1;i<=n;i++){
dp[i]=dp[i-1];
for(j=1;j<=i;j++)if(~f[j][i])up(dp[i],dp[j-1]+f[j][i]);
}
printf("%d",dp[n]);
}

  

E. Ingredients

拓扑排序之后背包即可。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 1e6 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
int B, n;
char s1[N][24];
char s2[N][24];
char s3[N][24];
int c[N];
int v[N];
int cc[N];
int vv[N];
int ind[N];
int sta[N];
map<string, int>mop;
int ID;
vector< pair<int,int> >a[N];
int getid(char s[24])
{
if(!mop.count(s))
{
mop[s] = ++ID;
a[ID].clear();
cc[ID] = inf;
vv[ID] = -inf;
ind[ID] = 0;
}
return mop[s];
}
bool e[N];
LL f[10005];
int main()
{
while(~scanf("%d%d", &B, &n))
{
ID = 0;
mop.clear();
for(int i = 1; i <= n; ++i)
{
scanf("%s%s%s%d%d", s1[i], s2[i], s3[i], &c[i], &v[i]);
int z = getid(s1[i]);
int x = getid(s2[i]);
int y = getid(s3[i]);
++ind[z];
a[x].push_back({y, i});
a[y].push_back({x, i});
e[i] = 0;
}
int top = 0;
for(int i = 1; i <= ID; ++i)if(ind[i] == 0)
{
sta[++top] = i;
cc[i] = vv[i] = 0;
}
while(top)
{
int x = sta[top--];
for(auto it : a[x])
{
int y = it.first;
int o = it.second;
if(!e[o] && ind[y] == 0)
{
e[o] = 1;
int z = mop[s1[o]];
int cost = cc[x] + cc[y] + c[o];
int val = vv[x] + vv[y] + v[o];
if(cost < cc[z] || cost == cc[z] && val > vv[z])
{
cc[z] = cost;
vv[z] = val;
}
if(--ind[z] == 0)
{
sta[++top] = z;
}
}
}
}
MS(f, -63); f[0] = 0;
for(int i = 1; i <= ID; ++i)
{
//
//printf("cc = %d, vv = %d\n", cc[i], vv[i]);
//
for(int j = B; j >= cc[i]; --j)
{
gmax(f[j], f[j - cc[i]] + vv[i]);
}
}
int cost = 0;
LL val = 0;
for(int i = 1; i <= B; ++i)
{
if(f[i] > val)
{
val = f[i];
cost = i;
}
}
printf("%lld\n%d\n", val, cost);
}
return 0;
} /*
【trick&&吐槽】
6 2
pizza_tomato pizza_base tomato 1 2
pizza_classic pizza_tomato cheese 5 5 7 2
pizza_tomato pizza_base tomato 1 2
pizza_classic pizza_tomato cheese 5 5 9 2
pizza_tomato pizza_base tomato 1 2
pizza_classic pizza_tomato cheese 5 5 100 2
pizza_tomato pizza_base tomato 1 2
pizza_classic pizza_tomato cheese 5 5 【题意】 【分析】 【时间复杂度&&优化】 */

  

F. Shattered Cake

$ans=\frac{\sum_{i=1}^n w_il_i}{W}$。

#include<cstdio>
int w,n;long long s;
int main(){
scanf("%d%d",&w,&n);
while(n--){
int x,y;
scanf("%d%d",&x,&y);
s+=x*y;
}
printf("%lld",s/w);
}

  

G. Cordon Bleu

考虑费用流建图,新建一个容量为$n-1$的虚点,表示从餐厅出发的快递员,剩下部分显然,然后求最小费用最大流。

这样边数为$O(n^2)$,不能接受。注意到这些边费用都是曼哈顿距离,将绝对值拆开后$4$个象限分别用可持久化线段树优化建图即可。

如此一来点数边数均为$O(n\log n)$,可以通过。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 70000, M = 1e6 + 10, Z = 1e9 + 7, inf = 1e9;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei; int id, ST, ED;
int first[N];
int w[M], c[M], cap[M], cost[M], nxt[M];
int f[N];
int pe[N];
bool e[N];
int tot; int FLAG=0; void ins(int x, int y, int cap_, int cost_)
{
if(!x||!y)return;
if(FLAG)swap(x,y);
id ++;
w[id] = y;
cap[id] = cap_;
cost[id] = cost_;
nxt[id] = first[x];
first[x] = id; id ++;
w[id] = x;
cap[id] = 0;
cost[id] = -cost_;
nxt[id] = first[y];
first[y] = id;
}
int q[N];
unsigned short head,tail; void inq(int x, int cost_)
{
if(cost_ >= f[x]) return;
f[x] = cost_;
//pe[x] = pe_;
if(e[x]) return; e[x] = 1;
// if(cost_<q[head])q[--head]=x;else
q[++tail]=x;
} int vis[N], tim;
int dfs(int x, int all)
{
if(x == ST) return all;
int use = 0;
vis[x] = tim;
for(int z = first[x]; z; z = nxt[z]) if(cap[z ^ 1]){
int y = w[z];
if(vis[y] != tim && f[y] + cost[z ^ 1] == f[x]){
int tmp = dfs(y, min(cap[z ^ 1], all - use));
cap[z ^ 1] -= tmp;
cap[z] += tmp;
use += tmp;
if(use == all) break;
}
}
return use;
}
bool spfa()
{
for(int i=0;i<=tot+10;i++)f[i]=inf;
cap[0] = inf;
head=1,tail=0;
inq(ST, 0);
while(head!=tail+1){
int x = q[head++]; e[x]=0;
for(int z = first[x]; z; z = nxt[z]){
if(cap[z]) inq(w[z], f[x] + cost[z]);
}
}
return f[ED] < inf;
} int MCMF()
{
int maxflow = 0;
int mincost = 0;
while(spfa()){
int flow;
while(++tim, flow = dfs(ED, inf))
{
maxflow += flow;
mincost += f[ED] * flow;
}
}
//printf("%d\n",maxflow);
return mincost;
} /*int MCMF()
{
int maxflow = 0;
int mincost = 0;
while(spfa()){
int flow = ~0U>>1;
int x = ED;
while(x != ST){
gmin(flow, cap[pe[x]]);
x = w[pe[x] ^ 1];
}
maxflow += flow;
mincost += f[ED] * flow;
x = ED;
while(x != ST){
cap[pe[x]] -= flow;
cap[pe[x] ^ 1] += flow;
x = w[pe[x] ^ 1];
}
}
return mincost;
//printf("%d %d\n", maxflow, mincost);
}*/ struct point
{
int x, y;
};
int dis(point a, point b)
{
return abs(a.x - b.x) + abs(a.y - b.y);
}
int n, m;
point a, b[N], cc[N];
int ans;
int pool[N];
inline bool cmpx(int x,int y){
return b[x].x<b[y].x;
}
int root0[1111],root1[1111];
int sonl[200000],sonr[200000];
int Ins(int x,int a,int b,int c,int p,int w){
int y=++tot;
if(a==b){
ins(y,x,inf,0);
ins(y,p,inf,w);
return y;
}
int mid=(a+b)>>1;
if(c<=mid){
sonl[y]=Ins(sonl[x],a,mid,c,p,w);
sonr[y]=sonr[x];
}else{
sonl[y]=sonl[x];
sonr[y]=Ins(sonr[x],mid+1,b,c,p,w);
}
ins(y,sonl[y],inf,0);
ins(y,sonr[y],inf,0);
return y;
}
void ask(int x,int a,int b,int c,int d,int p,int w){
if(!x)return;
if(c<=a&&b<=d){
ins(p,x,inf,w);
return;
}
int mid=(a+b)>>1;
if(c<=mid)ask(sonl[x],a,mid,c,d,p,w);
if(d>mid)ask(sonr[x],mid+1,b,c,d,p,w);
}
void solve()
{
MS(first, 0); id = 1;
ED = m + n + 1;
ST = m + n + 4;
int R = m + n + 2;
for(int i = 1; i <= m; i ++)
{
ins(ST, i, 1, 0);
/*for(int j = 1; j <= n; j ++)
{
ins(i, j + m, 1, dis(cc[i], b[j]));
}*/
} tot=ST; for(int i=1;i<=n;i++)pool[i]=i;
sort(pool+1,pool+n+1,cmpx); root0[0]=root1[0]=0;
for(int i=1;i<=n;i++){
int x=pool[i];
root0[i]=Ins(root0[i-1],0,2000,b[x].y,x+m,-b[x].x-b[x].y);
root1[i]=Ins(root1[i-1],0,2000,b[x].y,x+m,-b[x].x+b[x].y);
}
for(int i=1;i<=m;i++){
int j=0;
int X=cc[i].x,Y=cc[i].y;
while(j<n&&b[pool[j+1]].x<=X)j++;
ask(root0[j],0,2000,0,Y,i,X+Y);
ask(root1[j],0,2000,Y,2000,i,X-Y);
} reverse(pool+1,pool+n+1);
for(int i=1;i<=n;i++){
int x=pool[i];
root0[i]=Ins(root0[i-1],0,2000,b[x].y,x+m,b[x].x-b[x].y);
root1[i]=Ins(root1[i-1],0,2000,b[x].y,x+m,b[x].x+b[x].y);
}
for(int i=1;i<=m;i++){
int j=0;
int X=cc[i].x,Y=cc[i].y;
while(j<n&&b[pool[j+1]].x>=X)j++;
ask(root0[j],0,2000,0,Y,i,-X+Y);
ask(root1[j],0,2000,Y,2000,i,-X-Y);
} for(int i = 1; i <= n; i ++)
{
ins(R, m + i, 1, dis(a, b[i]));
ins(m + i, ED, 1, 0);
}
ins(ST, R, n - 1 , 0);
//printf("%d %d\n",tot,id);return;
if(FLAG)swap(ST,ED); ans += MCMF();
printf("%d\n", ans);
}
inline void getnum(int &x){
scanf("%d",&x);
//x=rand()%2001-1000;
x+=1000;
}
int main()
{
scanf("%d%d", &n, &m);//huowu ren
for(int i = 1; i <= n; i ++){
getnum(b[i].x);
getnum(b[i].y);
}
for(int i = 1; i <= m; i ++){
getnum(cc[i].x);
getnum(cc[i].y);
}
getnum(a.x);
getnum(a.y); ans = 0;
for(int i = 1; i <= n; ++i)
{
ans += dis(a, b[i]);
} solve();
return 0;
} /*
【trick&&吐槽】
3 10
0 0
10 0
0 10 【题意】 【分析】 【时间复杂度&&优化】 */

  

H. Kabobs

留坑。

I. Burglary

设$f[i][j][k]$表示考虑从上往下前$i$行,目前两条路线分别位于第$i$行的第$j$和第$k$根管道上的最大收益,暴力转移即可。

时间复杂度$O(10^4n)$。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 1005, M = 5005, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
int n, m;
char s[M];
int gv[N];
int v[N][M];
int p[N][M];
int gt[N];
int t[N][M];
int sum[N][M];
int f[N][12][12];
int main()
{
while (~scanf("%d%d", &n, &m))
{
for (int i = 1; i <= n; ++i)
{
scanf("%s", s + 1);
gv[i] = 0;
p[i][0] = 0;
v[i][0] = 0;
for (int j = 1; j <= m; ++j)if (isdigit(s[j]))
{
v[i][++gv[i]] = s[j] - '0';
p[i][gv[i]] = j;
}
++gv[i];
p[i][gv[i]] = m + 1;
v[i][gv[i]] = 0;
for (int j = 1; j <= gv[i]; ++j)
{
sum[i][j] = sum[i][j - 1] + v[i][j];
}
//
scanf("%s", s + 1);
gt[i] = 0;
for (int j = 1; j <= m; ++j)if (s[j] == '|')
{
t[i][++gt[i]] = j;
}
}
MS(f, -63);
MS(f[1], 0);
for (int o = 1; o < n; ++o)
{
for (int i = 1; i <= gt[o]; ++i)
{
for (int j = i; j <= gt[o]; ++j)if (f[o][i][j] >= 0)
{
for (int ii = 1; ii <= gt[o + 1]; ++ii)
{
for (int jj = ii; jj <= gt[o + 1]; ++jj)
{
int l1 = min(t[o][i], t[o + 1][ii]);
int r1 = max(t[o][i], t[o + 1][ii]); int l2 = min(t[o][j], t[o + 1][jj]);
int r2 = max(t[o][j], t[o + 1][jj]); int ll1 = lower_bound(p[o + 1], p[o + 1] + gv[o + 1] + 1, l1) - p[o + 1];
int rr1 = upper_bound(p[o + 1], p[o + 1] + gv[o + 1] + 1, r1) - p[o + 1] - 1; int ll2 = lower_bound(p[o + 1], p[o + 1] + gv[o + 1] + 1, l2) - p[o + 1];
int rr2 = upper_bound(p[o + 1], p[o + 1] + gv[o + 1] + 1, r2) - p[o + 1] - 1; //
int ll = max(ll1, ll2);
int rr = min(rr1, rr2);
if (ll <= rr)
{
int inside = sum[o + 1][rr]; if (ll)inside -= sum[o + 1][ll - 1];
if (inside)continue;
} l1 = upper_bound(p[o + 1], p[o + 1] + gv[o + 1] + 1, l1) - p[o + 1] - 1;
r1 = lower_bound(p[o + 1], p[o + 1] + gv[o + 1] + 1, r1) - p[o + 1]; l2 = upper_bound(p[o + 1], p[o + 1] + gv[o + 1] + 1, l2) - p[o + 1] - 1;
r2 = lower_bound(p[o + 1], p[o + 1] + gv[o + 1] + 1, r2) - p[o + 1]; //
if (l1 > l2)
{
swap(l1, l2);
swap(r1, r2);
}
//one segment
int val;
if (l2 <= r1 + 1)
{
int l = l1;
int r = max(r1, r2);
val = sum[o + 1][r]; if (l)val -= sum[o + 1][l - 1]; }
//two segment
else
{
val = sum[o + 1][r1]; if (l1)val -= sum[o + 1][l1 - 1];
val += sum[o + 1][r2]; if (l2)val -= sum[o + 1][l2 - 1];
}
gmax(f[o + 1][ii][jj], f[o][i][j] + val);
}
}
}
}
} int ans = 0;
for (int o = 1; o <= n; ++o)
{
for (int i = 1; i <= gt[o]; ++i)
{
for (int j = i; j <= gt[o]; ++j)if (f[o][i][j] >= 0)
{
int l = t[o][i];
int r = t[o][j];
l = upper_bound(p[o + 1], p[o + 1] + gv[o + 1] + 1, l) - p[o + 1] - 1;
r = lower_bound(p[o + 1], p[o + 1] + gv[o + 1] + 1, r) - p[o + 1];
int val = sum[o + 1][r]; if (l)val -= sum[o + 1][l - 1];
gmax(ans, f[o][i][j] + val);
}
}
}
printf("%d\n", ans);
}
return 0;
} /*
【trick&&吐槽】 【题意】 【分析】 【时间复杂度&&优化】
5 20
--------------------
.|.....|...|......|.
1-1--1115-3-1-1--1-1
....|.........|.....
---1-11-1-11---1--3-
.......|.........|..
-7----9-4-----------
..|.................
--------9-----------
.|.................| */

  

J. Frosting on the Cake

按题意模拟即可。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 0, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
int n;
LL a[3], b[3], c[3];
int main()
{
while(~scanf("%d",&n))
{
MS(a, 0); MS(b, 0); MS(c, 0);
for(int i = 1; i <= n; ++i)
{
int x; scanf("%d", &x);
a[i % 3] += x;
}
for(int i = 1; i <= n; ++i)
{
int x; scanf("%d", &x);
b[i % 3] += x;
}
for(int i = 0; i < 3; ++i)
{
for(int j = 0; j < 3; ++j)
{
c[(i + j) % 3] += a[i] * b[j];
}
}
printf("%lld %lld %lld\n", c[0], c[1], c[2]);
}
return 0;
} /*
【trick&&吐槽】 【题意】 【分析】 【时间复杂度&&优化】 */

  

K. Blowing Candles

求凸包后旋转卡壳,注意特判所有点共线的情况。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 2e5 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
LL sqr(LL x)
{
return x * x;
}
struct point
{
LL x, y;
point(){}
point(LL x, LL y) : x(x), y(y) {}
friend point operator + (const point &a, const point &b){
return point(a.x + b.x, a.y + b.y);
}
friend point operator - (const point &a, const point &b){
return point(a.x - b.x, a.y - b.y);
}
friend point operator * (const point &a, const double &b){
return point(a.x * b, a.y * b);
}
friend point operator / (const point &a, const double &b){
return point(a.x / b, a.y / b);
}
friend bool operator == (const point &a, const point &b){
return a.x == b.x && a.y == b.y;
}
};
LL det(point a, point b)
{
return a.x * b.y - a.y * b.x;
}
LL dot(point a, point b)
{
return a.x * b.x + a.y * b.y;
}
LL dist(point a, point b)
{
return sqr(a.x - b.x) + sqr(a.y - b.y);
}
struct polygon_convex
{
vector<point> p;
polygon_convex(int size = 0){
p.resize(size);
}
};
bool comp_less(const point &a, const point &b)
{
return a.x - b.x < 0 || a.x - b.x == 0 && a.y - b.y < 0;
}
polygon_convex convex_hull(vector<point> a)
{
polygon_convex res(2 * a.size() + 5);
sort(a.begin(), a.end(), comp_less);
a.erase(unique(a.begin(), a.end()), a.end());
int m = 0;
for(int i = 0; i < a.size(); i ++){
while(m > 1 && det(res.p[m - 1] - res.p[m - 2], a[i] - res.p[m - 2]) <= 0) -- m;
res.p[m ++] = a[i];
}
int k = m;
for(int i = int(a.size()) - 2; i >= 0; i --){
while(m > k && det(res.p[m - 1] - res.p[m - 2], a[i] - res.p[m - 2]) <= 0) -- m;
res.p[m ++] = a[i];
}
res.p.resize(m);
if(a.size() > 1) res.p.resize(m - 1);
return res;
} LL cross(point a, point b, point c)
{
return (c.x - a.x) * (b.y - a.y) - (b.x - a.x) * (c.y - a.y);
}
int R; double rotating_calipers(point *p, int n)
{
int U = 1;
double ans = 2.0 * R;
p[n] = p[0];
for(int i = 0; i < n; i ++){
while(cross(p[i], p[i + 1], p[U + 1]) - cross(p[i], p[i + 1], p[U]) <= 0) U = (U + 1) % n;
double d = sqrt(dist(p[i], p[i + 1]));
double h = 1.0 * fabs(cross(p[i], p[i + 1], p[U])) / d;
gmin(ans, h);
}
return ans;
}
int n;
point t, p[N];
polygon_convex a;
int main()
{
scanf("%d%d", &n, &R);
for(int i = 0; i < n; i ++){
scanf("%lld%lld", &t.x, &t.y);
a.p.push_back(t);
}
a = convex_hull(a.p);
n = a.p.size();
for(int i = 0; i < n; i ++){
p[i] = a.p[i];
}
double ans;
if(n <= 2){
printf("0.000000000");
}
else {
ans = rotating_calipers(p, n);
printf("%.10f\n", ans);
}
return 0;
} /*
【trick&&吐槽】
3 10
0 0
10 0
0 10 【题意】 【分析】 【时间复杂度&&优化】 */

  

2017-2018 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2017)的更多相关文章

  1. Gym 2009-2010 ACM ICPC Southwestern European Regional Programming Contest (SWERC 2009) A. Trick or Treat (三分)

    题意:在二维坐标轴上给你一堆点,在x轴上找一个点,使得该点到其他点的最大距离最小. 题解:随便找几个点画个图,不难发现,答案具有凹凸性,有极小值,所以我们直接三分来找即可. 代码: int n; lo ...

  2. 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)

    A. Within Arm's Reach 留坑. B. Bribing Eve 枚举经过$1$号点的所有直线,统计直线右侧的点数,旋转卡壳即可. 时间复杂度$O(n\log n)$. #includ ...

  3. 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016) F dfs序+树状数组

    Performance ReviewEmployee performance reviews are a necessary evil in any company. In a performance ...

  4. 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016) B - Bribing Eve

    地址:http://codeforces.com/gym/101174/attachments 题目:pdf,略 思路: 把每个人的(x1,x2)抽象成点(xi,yi). 当1号比i号排名高时有==& ...

  5. 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016) D.Dinner Bet 概率DP+排列组合

    题目链接:点这里 题意: 1~N标号的球 现在A有C个,B有C个 每次可以随机得到D个不同的球(1~N);问你A或B中的C个球都出现一次的 期望次数 题解: dp[i][j][k]表示 随机出现了i个 ...

  6. 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016) E.Passwords AC自动机+dp

    题目链接:点这里 题意: 让你构造一个长度范围在[A,B]之间 字符串(大小写字母,数字),问你有多少种方案 需要满足条件一下: 1:构成串中至少包含一个数字,一个大写字母,一个小写字母:   2:不 ...

  7. 2017-2018 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2017)

    2017-2018 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2017) 全靠 wxh的博客 补完这套.wx ...

  8. 2017-2018 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2017) Solution

    A:Concerts 题意:给出一个串T, 一个串S,求串S中有多少个串T,可以重复,但是两个字符间的距离要满足给出的数据要求 思路:先顺序统计第一个T中的字符在S中有多少个,然后对于第二位的以及后面 ...

  9. 2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2018)

    layout: post title: 2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 201 ...

随机推荐

  1. 【GDOI2016模拟3.16】幂(容斥 + 模型复杂转化)

    [GDOI2016模拟3.16]幂 \(X\in[1,A],Y\in[1,B]\),问:\(x^y\)的不用取值个数. \(A,B\)都是\(10^9\)级别. 然后我们开搞. 首先,假设一个合法的\ ...

  2. Vue(项目踩坑)_解决vue中axios请求跨域的问题

    一.前言 今天在做项目的时候发现axios不能请求跨域接口 二.主要内容 1.之前直接用get方式请求聚合数据里的接口报错如下 2.当前请求的代码 3.解决方法 (1)在项目目录中依次找到:confi ...

  3. Redis的Cluster配置

    Redis的Cluster配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.安装Redis并启动 1>.修改Redis的配置文件(本实验只有三个节点) [root@no ...

  4. SQL Server数据库的备份和还

    转:http://blog.csdn.net/zwj7612356/article/details/8188025 在sql server数据库中,备份和还原都只能在服务器上进行,备份的数据文件在服务 ...

  5. LCA(Tarjan)

    时间复杂度:dfs为O(N),dfs过程中处理所有查询对为O(M),总时间复杂度O(N+M) #include<iostream> #include<cstdio> using ...

  6. Vim使用技巧汇总

    一 写在开头 1.1 本文内容 Vim使用技巧与学习资源汇总. 二 Vim学习资源 1. Vimtutor 2. Vim中文帮助(http://vimcdoc.sourceforge.net/doc/ ...

  7. bash 特殊变量

    脚本参数 $* $@ $N shift 执行一个脚本时可以传递参数, 事实上每个参数都有对应的变量$0~$9 ./start.sh  a   b   c $0           $1 $2 $3 当 ...

  8. [物理学与PDEs]第2章第3节 Navier-Stokes 方程组

    1.  当流体的压力 $p$ 及温度 $T$ 改变时, 密度 $\rho$ 变化很小. 此时可近似地把流体看作是不可压的, 而 $\rho=\const$. 如此, 流体动力学方程组中的质量.动量守恒 ...

  9. Jquery+php 动态web表单增删改查

    如这类效果: 例一:简单 <html> <head> <meta http-equiv="content-type" content="te ...

  10. 《我是一只IT小小鸟读后感》

    在我步入大学前,并未了解何为IT,真是毫无知晓.由于种种原因最终还是选择了软件工程专业,是 对是错,是福是祸,不知该不该去考虑,但即已然 选择了这条路,便得付出一些努力,这个世界总 是有许多在默默努力 ...