来自FallDream的博客。未经允许,请勿转载,谢谢。

----------------------------------------------------

A.积分,不会  以后补

B.给定一个n*m的矩阵,每个点是0或者1,然后q个操作,每次把一个位置取反,然后询问最大的全是1的正方形的边长。n*m<=4000000 , q<=3900

题解:我们用一个线段树把所有行维护起来,然后每一行对每一列维护这个行区间的这一列的u和d,u表示从最下面一个最多有多少个连续的1,d表示从上面网下面最多有多少个连续的1,这两个参数是很好合并的。然后我们考虑计算过中线的答案。我们用两个指针ij,再用两个单调队列,维护u和d单调下降。每当 i - j + 1> u[tail] + d[tail] 的时候,我们把j指针往前移。最后我们用i - j + 1更新答案。

复杂度qmlogn  如果n<m我们把nm交换一下。

最近被奇怪的代码风格洗脑了,写了一个不像是我写的程序(听我解释,我真的不是抄的.....) 其实我真正的代码风格像C题那样就是一团垃圾

#include<iostream>
#include<cstdio>
#define MN 2000
#define TEST
using namespace std;
inline int read()
{
int x = , f = ; char ch = getchar();
while(ch < '' || ch > ''){ if(ch == '-') f = -; ch = getchar();}
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return x * f;
} inline int cread()
{
char ch = getchar();
while(ch != '.' && ch != 'X') ch = getchar();
return ch == '.' ? : ;
} int n , m , q , qx[MN + ] , ltop , qy[MN + ] , rtop , ltail , rtail;
bool *s[MN + ] , rev; struct Segment_Tree{
int ans , w;
int *u , *d;
Segment_Tree *l , *r;
void init(int x)
{
ans = ;
for(int i = ; i <= n ; ++i)
u[i] = d[i] = s[i][x] , ans |= s[i][x];
} void update()
{
ans = max ( l->ans , r->ans ); int x , k = ;
for(int i = ; i <= n ; ++i)
{
u[i] = l -> d[i];
d[i] = r -> u[i];
} qx[ltop = ] = qy[rtop = ] = ;
ltail = rtail = ; for ( int i = ; i <= n ; ++i)
{
while(u[i] <= u[qx[ltop]] && ltop >= ltail) ltop --;
while(d[i] <= d[qy[rtop]] && rtop >= rtail) rtop --; qx[++ ltop] = i;
qy[++ rtop] = i; while(i - k + > u[qx[ltail]] + d[qy[rtail]] && i > k)
{
++ k;
if(qx[ltail] < k) ltail ++;
if(qy[rtail] < k) rtail ++;
}
ans = max(ans , i - k + );
} for(int i = ; i <= n ; ++i)
{
u[i] = ( l -> u[i] == l -> w) ? r -> u[i] + l -> w : l -> u[i];
d[i] = ( r -> d[i] == r -> w) ? l -> d[i] + r -> w : r -> d[i];
}
} void modify(int x , int lt = , int rt = m)
{
if(lt == rt) { init(x); return;}
int mid = lt + rt >> ;
if(x <= mid) l -> modify(x , lt , mid);
else r -> modify(x , mid + , rt);
update();
} Segment_Tree(int lt , int rt )
{
u = new int [n + ];
d = new int [n + ];
w = rt - lt + ;
if(lt == rt) { init(lt); return;}
int mid = lt + rt >> ;
l = new Segment_Tree(lt , mid);
r = new Segment_Tree(mid + , rt);
update();
} }*rt; int main()
{
#ifdef TEST
freopen("s.in" , "r" , stdin);
freopen("s.out" , "w" , stdout);
#endif n = read(); m = read(); q = read();
if( n > m) swap(n , m),rev = true;
for(int i = ; i <= n ; ++i)
s[i] = new bool [m + ]; if(!rev)
for(int i = ; i <= n ; ++i)
for(int j = ; j <= m ; ++j)
s[i][j] = cread();
else
for(int i = ; i <= m ; ++i)
for(int j = ; j<= n ; ++j)
s[j][i] = cread(); rt = new Segment_Tree( , m); for(int i = ; i <= q ; ++i)
{
int x = read() , y = read();
if(rev) swap(x , y);
s[x][y] ^= ;
rt -> modify(y);
printf("%d\n" , rt -> ans);
}
return ;
}

C.给定一棵n个点树,每个点可以涂成白的或者黑的。给定b条链和b个权值bi,表示这条链上的点全是黑色时候能得到bi的贡献。还有a条链和a个权值,表示全部涂成白色能得到的贡献。你要求出最大贡献。n<=100000  a,b<=30000  3s

题解:神题

最小割,很显然黑白链就是一个二分图。但是直接建图是不行的,所以我们考虑优化一下,把树拿去树剖一下,然后建两棵线段树,一棵只能往下走,一棵只能往上走。每条链对两棵线段树上的对应的log个区间建边,最后跑一次最小割。复杂度很玄学,就算O(能过)吧。

ditoly真的强,居然在现场想出了这个做法...%%%

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 800000
#define MAXL 10000000
#define MV 860000
#define MAXN 100000
#define MN 100000
#define S 0
#define tt 860001
#define INF 2000000000
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-; ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-''; ch=getchar();}
return x*f;
}
int dn=,cnt=,ans=,n,B,W,head2[MAXN+],head[MV+],top[MAXN+],qx[MV+],qtop,tail;
int dfn[MAXN+],mx[MAXN+],size[MAXN+],dep[MAXN+],fa[MAXN+],q[MV+],tp[MV+];
struct edge{
int to,next,w;
}e[MAXL*+];
struct edge2{
int to,next;
}e2[MAXN*+];
struct TREE{
int l,r;
}T[MN*+]; inline void ins(int f,int t){e2[++cnt].next=head2[f];head2[f]=cnt;e2[cnt].to=t;}
inline void ins(int f,int t,int w){e[++cnt].next=head[f];head[f]=cnt;e[cnt].to=t;e[cnt].w=w;}
inline void insw(int f,int t,int w){ins(f,t,w);ins(t,f,);} void dfs(int x,int f)
{
size[x]=;mx[x]=;fa[x]=f;int maxn=;
for(int i=head2[x];i;i=e2[i].next)if(e2[i].to!=f)
{
dep[e2[i].to]=dep[x]+;dfs(e2[i].to,x);
size[x]+=size[e2[i].to];
if(size[e2[i].to]>maxn){maxn=size[e2[i].to];mx[x]=e2[i].to;}
}
} void dfs2(int x,int t)
{
top[x]=t;dfn[x]=++dn;
if(mx[x])dfs2(mx[x],t);
for(int i=head2[x];i;i=e2[i].next)if(!dfn[e2[i].to])
{dfs2(e2[i].to,e2[i].to);}
} void build(int x,int l,int r)
{
T[x].l=l;T[x].r=r;if(l==r)return;
int mid=(l+r)>>;
insw(x,x<<,INF);insw(x,x<<|,INF);
insw((x<<)+*MN,x+*MN,INF);insw((x<<|)+*MN,x+*MN,INF);
build(x<<,l,mid);build(x<<|,mid+,r);
} void insert(int from,int x,int l,int r)
{
// cout<<"insert"<<from<<" "<<x<<" "<<l<<" "<<r<<" "<<lt<<" "<<rt<<endl;
if(T[x].l==l&&T[x].r==r){insw(from,x,INF);insw(from,x+MN*,INF);return;}
int mid=(T[x].l+T[x].r)>>;
if(r<=mid)insert(from,x<<,l,r);
else if(l>mid)insert(from,x<<|,l,r);
else {insert(from,x<<,l,mid);insert(from,x<<|,mid+,r);}
} void insert2(int to,int x,int l,int r)
{
// cout<<"insert2"<<to<<" "<<x<<" "<<l<<" "<<r<<" "<<lt<<" "<<rt<<endl;
if(T[x].l==l&&T[x].r==r){insw(x,to,INF);insw(x+MN*,to,INF);return;}
int mid=(T[x].l+T[x].r)>>;
if(r<=mid)insert2(to,x<<,l,r);
else if(l>mid)insert2(to,x<<|,l,r);
else {insert2(to,x<<,l,mid);insert2(to,x<<|,mid+,r);}
} bool bfs()
{
memset(q,,sizeof(q));int i,j;
for(q[qx[qtop=i=]=S]=;i<=qtop;i++)
for(int j=tp[qx[i]]=head[qx[i]];j;j=e[j].next)if(!q[e[j].to]&&e[j].w)
q[qx[++qtop]=e[j].to]=q[qx[i]]+;
return q[tt]>;
} int solve(int x,int f)
{
// cout<<"solve"<<x<<" "<<f<<endl;
if(x==tt)return f;int used=;
for(int&i=tp[x];i;i=e[i].next)
if(e[i].w&&q[e[i].to]==q[x]+)
{
int w=solve(e[i].to,min(f-used,e[i].w));
used+=w;e[i].w-=w;e[i^].w+=w;
if(e[i].w) tp[x]=i;
if(used==f)return f;
}
if(!used)q[x]=-;
return used;
} int main()
{
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
n=read();B=read();W=read();
for(int i=;i<n;i++)
{int u=read(),v=read();ins(u,v),ins(v,u);}
cnt=;dfs(,);dfs2(,);
build(,,n);
for(int i=;i<=B;++i)
{
int u=read(),v=read(),x=read();insw(S,N+i,x);ans+=x;
while(top[u]!=top[v])
{
// cout<<u<<" "<<v<<" "<<top[u]<<" "<<top[v]<<endl;
if(dep[top[u]]>dep[top[v]])
{insert(N+i,,dfn[top[u]],dfn[u]);u=fa[top[u]];}
else
{insert(N+i,,dfn[top[v]],dfn[v]);v=fa[top[v]];}
}
if(dfn[u]>dfn[v])swap(u,v);insert(N+i,,dfn[u],dfn[v]);
}
for(int i=;i<=W;++i)
{
int u=read(),v=read(),x=read();insw(N+i+B,tt,x);ans+=x;
while(top[u]!=top[v])
{
// cout<<u<<" "<<v<<" "<<top[u]<<" "<<top[v]<<endl;
if(dep[top[u]]>dep[top[v]])
{insert2(N+i+B,,dfn[top[u]],dfn[u]);u=fa[top[u]];}
else
{insert2(N+i+B,,dfn[top[v]],dfn[v]);v=fa[top[v]];}
}
if(dfn[u]>dfn[v])swap(u,v);insert2(N+i+B,,dfn[u],dfn[v]);
}
while(bfs())ans-=solve(S,INF);
printf("%d\n",ans);
return ;
}

[3.19FJ四校联考]的更多相关文章

  1. [2017/5/28]FJ四校联考

    来自FallDream的博客,未经允许,请勿转载,谢谢. 话说这一段时间算是过去了,好久好久之后终于又有联考了  没想到这次到我们学校出题,昨天才想起来,临时花一天赶了一套,我出了一个sbFFT,质量 ...

  2. [四校联考P3] 区间颜色众数 (主席树)

    主席树 Description 给定一个长度为 N 颜色序列A,有M个询问:每次询问一个区间里是否有一种颜色的数量超过了区间的一半,并指出是哪种颜色. Input 输入文件第一行有两个整数:N和C 输 ...

  3. 四校联考 tree3

    我们考虑计算红色点与非红色点的对数. 我们用f[i][j]表示i的子树中有j个红色点的概率,将i所有子树合并. 接着我们对于每一个状态,枚举i是红色还是非红色算概率. 同时我们可以求出i和i子树内一个 ...

  4. 【四校联考】【比赛题解】FJ NOIP 四校联考 2017 Round 7

    此次比赛为厦门一中出题.都是聚劳,不敢恭维. 莫名爆了个0,究其原因,竟然是快读炸了……很狗,很难受. 话不多说,来看看题: [T1] 题意: 样例: PS:1<=h[i]<=100000 ...

  5. szoj461【四校联考0430】挑战

    传送门:(涉及版权忽略) [题解] 我们发现n的范围很小,提示我们可以折半,然后我们就会了O(T2^(n/2)*n)的做法,然而会T. 考虑如何优化.直接排序会多一个log(2^(n/2))也就是n, ...

  6. 三校联考 Day3

    三校联考 Day3 大水题 题目描述:给出一个圆及圆上的若干个点,问两个点间的最远距离. solution 按极角排序,按顺序枚举,显然距离最远的点是单调的,线性时间可解出答案. 大包子的束缚 题目描 ...

  7. 【赛时总结】NOIP2018-三校联考1024

    ◇NOIP三校联考-1024◇ 发现以前的博客写得似乎都很水……基本上都没什么阅读量QwQ 决定改过自新╰( ̄ω ̄o) 就从这篇博客开始吧~ 现场考得无地自容,看到题解才发现一些东西……(我第三题还没 ...

  8. [2019多校联考(Round 6 T3)]脱单计划 (费用流)

    [2019多校联考(Round 6 T3)]脱单计划 (费用流) 题面 你是一家相亲机构的策划总监,在一次相亲活动中,有 n 个小区的若干男士和 n个小区的若干女士报名了这次活动,你需要将这些参与者两 ...

  9. [多校联考2019(Round 5 T1)] [ATCoder3912]Xor Tree(状压dp)

    [多校联考2019(Round 5)] [ATCoder3912]Xor Tree(状压dp) 题面 给出一棵n个点的树,每条边有边权v,每次操作选中两个点,将这两个点之间的路径上的边权全部异或某个值 ...

随机推荐

  1. python 中os.path.join 双斜杠的解决办法

    这两天在写东西的时候遇到了这个问题,主要是上传图片之后,无法在页面展示,原因就出在用join 拼接的路径中出现了"\"而造成的. >>> import os &g ...

  2. 关于PHP7

    目前一直使用php7也看了许多文档视频等,整理一下相关细节(仅为记录-),对于PHP7性能,如下图所示. * 在wordpress3.0.1中 php7比php5.6性能提升约3倍左右 新特性 一.变 ...

  3. Python内置函数(50)——issubclass

     英文文档: issubclass(class, classinfo) Return true if class is a subclass (direct, indirect or virtual) ...

  4. maven常见问题处理(3-2)maven打包时跳过测试的几个方法

    运行mvn install时跳过Test方法一:<project> [...] <build> <plugins> <plugin> <group ...

  5. OAuth2.0学习(1-5)授权方式2-简化模式(implicit grant type)

    授权方式2-简化模式(implicit grant type) 简化模式(implicit grant type)不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授 ...

  6. window.open()参数详解及对浏览器的兼容性

    因为篇幅,window.open()浏览器的兼容性请点击 这里 Part1:参数详解 window.open(url,name,param) url:即将打开的子窗口的地址:比如 "http ...

  7. ssh整合之三hibernate和spring整合

    1.拷贝我们的spring事务控制所需的jar包 2.在spring容器中配置我们的hibernateTemplate以及事务管理器 <?xml version="1.0" ...

  8. Oracle12c在Win10上的安装配置实践

    1.环境 操作系统:Win10专业版(64位) 数据库:Oracle 12c Release 2(Version 12.2.0.1.0,64位) 2.下载Oracle12c oracle官网下载地址: ...

  9. zoj 3950 how many nines

    https://vjudge.net/problem/ZOJ-3950 题意: 给出两个日期,计算从第一个日期开始到第二个日期,每一天的日期中的9加起来一共有多少个. 思路: 看题解补的题.首先看这题 ...

  10. 智能提示含查询多列(html+JS+handler+ HttpRemoting)一、html示列 加 JS加 请求 Handler

    <html> <head> </head> <body> <form id="recordform" name="r ...